Lovely RouterDocs
Get a key
Data tools

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 toCall
See every tool, or one categoryGET /v1/tools
Find tools for a short query like "tiktok comments"POST /v1/tools/discover
Describe a whole task and get a plan with costsPOST /v1/tools/suggest
Read one tool's input schema, example and priceGET /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 as reviews or lead-generation. See categories.
  • q: keywords. Results are ranked by relevance, up to 100.
  • lang: zh or ja to localize tool names and descriptions. The default is English.
cURL
curl "https://lovelyrouter.com/v1/tools?category=reviews"

The response is a list of tool objects (trimmed to one here):

JSON
{
  "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
curl https://lovelyrouter.com/v1/tools/discover \
  -H "content-type: application/json" \
  -d '{"query": "google maps reviews", "limit": 3}'
JSON
{
  "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
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:

JSON
{
  "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#

  • role says how a step fits: primary is the tool to run first, next gets a second kind of data the task asks for (here, reviews of the places found in step 1), and alternative is a close runner-up you could use instead of the primary.
  • match is the planner's confidence in that step, from 0 to 1.
  • input is the tool's example input, not one written for your task. Replace its values with yours: above, "coffee shop" becomes "vegan restaurant". input_required lists the fields you must set. For the full schema, call GET /v1/tools/{id}.
  • est_cost_usd is the most the step costs at the max_results shown, which is the tool's default cap. Change max_results and the cost scales with it.
  • total_est_cost_usd adds up the primary and next steps. Alternatives are not included because you run them instead, not as well.
  • run is a ready-made request for Run a tool: send body to path once 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:

CallerLimit
With an API key100 requests per minute per key
Without a key100 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
curl https://lovelyrouter.com/v1/tools/trustpilot-reviews

The response, trimmed:

JSON
{
  "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
curl "https://lovelyrouter.com/v1/tools/google-maps-reviews?lang=ja"

Next steps#