Find the right tool
Browse the catalog, search it by keyword, describe a task to get an ordered plan with costs, and read a tool's input schema before you run it.
The catalog endpoints are public and free. You can call them without a key, and agents can call them as often as they need to pick the right tool. Four endpoints cover the search:
| You want to | Call |
|---|---|
| See every tool, or one category | GET /v1/tools |
| Find tools for a short query like "tiktok comments" | POST /v1/tools/discover |
| Describe a whole task and get a plan with costs | POST /v1/tools/suggest |
| Read one tool's input schema, example and price | GET /v1/tools/{id} |
Browse the catalog#
GET /v1/tools returns every available tool with its price. Narrow the list with query parameters:
category: one category id, such asreviewsorlead-generation. See categories.q: keywords. Results are ranked by relevance, up to 100.lang:zhorjato localize tool names and descriptions. The default is English.
curl "https://lovelyrouter.com/v1/tools?category=reviews"The response is a list of tool objects (trimmed to one here):
{
"object": "list",
"data": [
{
"id": "google-maps-reviews",
"name": "Google Maps reviews",
"platform": "Google Maps",
"category": "reviews",
"description": "Reviews of a Google Maps place (by place ID or URL): text, stars, date, owner replies.",
"price": {
"per_call_usd": 0,
"per_result_usd": 0.000675,
"unit": "review",
"label": "$0.000675 / review"
},
"default_results": 20,
"max_results": 500,
"featured": false
}
]
}The price object is the live price. default_results is the result cap a run uses when you don't set max_results, and max_results is the highest cap the tool accepts. Every field is described in the tool object.
Search by keyword#
POST /v1/tools/discover takes a short query and returns the best matches with a relevance score. Platform and tool names weigh more than descriptions, so a query that names a platform ranks that platform's tools first.
curl https://lovelyrouter.com/v1/tools/discover \
-H "content-type: application/json" \
-d '{"query": "google maps reviews", "limit": 3}'{
"query": "google maps reviews",
"count": 3,
"results": [
{
"id": "google-maps-reviews",
"name": "Google Maps reviews",
"platform": "Google Maps",
"category": "reviews",
"price": { "per_call_usd": 0, "per_result_usd": 0.000675, "unit": "review", "label": "$0.000675 / review" },
"default_results": 20,
"max_results": 500,
"score": 0.889
},
{
"id": "google-maps-places",
"name": "Search Google Maps places",
"platform": "Google Maps",
"category": "search",
"price": { "per_call_usd": 0.00075, "per_result_usd": 0.000238, "unit": "place", "label": "$0.000238 / place + $0.00075 / call" },
"default_results": 10,
"max_results": 200,
"score": 0.717
},
{
"id": "google-maps-leads",
"name": "Google Maps leads with emails",
"platform": "Google Maps",
"category": "lead-generation",
"price": { "per_call_usd": 0, "per_result_usd": 0.00075, "unit": "place", "label": "$0.00075 / place" },
"default_results": 10,
"max_results": 200,
"score": 0.556
}
]
}limit defaults to 5 and goes up to 40. Use score to order results, not as an absolute measure: it only compares tools for the same query.
Plan a task#
When a task needs more than one tool, or you don't know which one fits, describe it in plain words. POST /v1/tools/suggest returns an ordered plan in under a second: the tool to run first, an optional second tool, and close alternatives, each with an example input and an estimated cost.
curl https://lovelyrouter.com/v1/tools/suggest \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{"task": "Find vegan restaurants in Austin and summarize what their reviews complain about"}'The response, trimmed:
{
"task": "Find vegan restaurants in Austin and summarize what their reviews complain about",
"source": "ai",
"cached": false,
"count": 2,
"suggestions": [
{
"step": 1,
"role": "primary",
"match": 0.961,
"id": "google-maps-places",
"name": "Search Google Maps places",
"price": { "per_call_usd": 0.00075, "per_result_usd": 0.000238, "unit": "place", "label": "$0.000238 / place + $0.00075 / call" },
"input": {
"searchTerms": ["coffee shop"],
"location": "Austin, Texas, USA",
"maxResults": 3,
"language": "en"
},
"input_required": [],
"max_results": 10,
"est_cost_usd": 0.00313,
"run": {
"method": "POST",
"path": "/v1/tools/google-maps-places/run",
"body": { "input": { "searchTerms": ["coffee shop"], "location": "Austin, Texas, USA", "maxResults": 3, "language": "en" }, "max_results": 10 }
}
},
{
"step": 2,
"role": "next",
"match": 0.875,
"id": "google-maps-reviews",
"name": "Google Maps reviews",
"price": { "per_call_usd": 0, "per_result_usd": 0.000675, "unit": "review", "label": "$0.000675 / review" },
"input": { "placeIds": ["ChIJN1t_tDeuEmsRUsoyG83frY4"], "maxReviews": 3, "reviewsSort": "newest" },
"input_required": [],
"max_results": 20,
"est_cost_usd": 0.0135,
"run": {
"method": "POST",
"path": "/v1/tools/google-maps-reviews/run",
"body": { "input": { "placeIds": ["ChIJN1t_tDeuEmsRUsoyG83frY4"], "maxReviews": 3, "reviewsSort": "newest" }, "max_results": 20 }
}
}
],
"total_est_cost_usd": 0.01663
}Read the plan#
rolesays how a step fits:primaryis the tool to run first,nextgets a second kind of data the task asks for (here, reviews of the places found in step 1), andalternativeis a close runner-up you could use instead of the primary.matchis the planner's confidence in that step, from 0 to 1.inputis the tool's example input, not one written for your task. Replace its values with yours: above,"coffee shop"becomes"vegan restaurant".input_requiredlists the fields you must set. For the full schema, callGET /v1/tools/{id}.est_cost_usdis the most the step costs at themax_resultsshown, which is the tool's default cap. Changemax_resultsand the cost scales with it.total_est_cost_usdadds up theprimaryandnextsteps. Alternatives are not included because you run them instead, not as well.runis a ready-made request for Run a tool: sendbodytopathonce you've filled in the input.
An empty suggestions list means no tool in the catalog fits the task, for example "write a poem". If the planner is unavailable, the endpoint falls back to keyword matches and sets source to keyword. Identical tasks are answered from a cache for a day, with cached: true.
Options and limits#
The body takes task (required, up to 2,000 characters), limit (number of suggestions, 1 to 8, default 5) and lang (zh or ja).
Planning is free, with a rate limit:
| Caller | Limit |
|---|---|
| With an API key | 100 requests per minute per key |
| Without a key | 100 requests per minute, shared by every anonymous caller |
Over the limit, the endpoint returns 429 with a retry-after header in seconds. Send your key for a limit of your own.
Inspect a tool#
Before you run a tool, read its input schema. GET /v1/tools/{id} returns the tool object plus input_schema (JSON Schema for input), an example_input that works as is, the run's time limit in timeout_s, and a ready-made run request.
curl https://lovelyrouter.com/v1/tools/trustpilot-reviewsThe response, trimmed:
{
"id": "trustpilot-reviews",
"name": "Trustpilot reviews",
"platform": "Trustpilot",
"category": "reviews",
"description": "Trustpilot reviews of a company by domain: stars, text, date, reply.",
"price": {
"per_call_usd": 0.0075,
"per_result_usd": 0.0015,
"unit": "review",
"label": "$0.0015 / review + $0.0075 / call"
},
"default_results": 20,
"max_results": 500,
"featured": false,
"input_schema": {
"type": "object",
"properties": {
"companyUrls": {
"type": "array",
"title": "Company URLs or Domains",
"description": "Enter Trustpilot company URLs (e.g., https://www.trustpilot.com/review/example.com) or just the domain (e.g., example.com). One per line."
},
"maxReviewsPerCompany": {
"type": "integer",
"title": "Max reviews per company (reviews)",
"description": "Maximum number of reviews to scrape per company. Set to 0 for unlimited reviews.",
"default": 0,
"minimum": 0
},
"sort": {
"type": "string",
"title": "Sort Order",
"enum": ["relevance", "recency"],
"default": "recency"
}
},
"required": ["companyUrls"]
},
"example_input": {
"companyUrls": ["pipedrive.com"],
"maxReviewsPerCompany": 20
},
"timeout_s": 300,
"run": {
"method": "POST",
"path": "/v1/tools/trustpilot-reviews/run",
"body": { "input": { "companyUrls": ["pipedrive.com"], "maxReviewsPerCompany": 20 }, "max_results": 20 }
}
}Field names and their meaning differ from tool to tool, so always build input from input_schema. You don't need to set the tool's own count field (here maxReviewsPerCompany) to control cost: max_results caps the run either way. The tools page shows the same schema for every tool, and you can try a tool there once you're signed in.
An unknown or retired tool id returns 404.
Localize names and descriptions#
Add lang=zh or lang=ja to any catalog request, as a query parameter on GET or as "lang" in a POST body. Tool names and descriptions come back translated. Ids, prices and input schemas stay the same.
curl "https://lovelyrouter.com/v1/tools/google-maps-reviews?lang=ja"