Prefer not to write code? Install the Nimble plugin and describe what you need in plain language. Onboard your Agent has the one-command setup for every coding agent.
Get your API key
Sign up and copy your key from Settings → API Keys. Then set it as an environment variable:Every SDK and the CLI read
export NIMBLE_API_KEY="your-api-key"
$env:NIMBLE_API_KEY="your-api-key"
NIMBLE_API_KEY automatically.Install a client
Requires Python 3.9+, Node.js 20 LTS+, or Go 1.22+.Full client docs: Python, Node, Go, and CLI. Python also offers an aiohttp extra:
pip install nimble_python
npm install @nimble-way/nimble-js
go get github.com/Nimbleway/nimble-go@latest
npm install -g @nimble-way/nimble-cli
pip install "nimble_python[aiohttp]".Calling the API over plain HTTP? Skip this step and see the API Reference.NIMBLE_API_KEY. The first Search example is a complete program; the rest are abbreviated and assume you have already created a client the same way.
Search
Real-time web search with structured results:import os
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
result = nimble.search(
query="latest developments in AI agents",
max_results=5
)
for r in result.results:
print(f"- {r.title}: {r.url}")
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
const result = await nimble.search({
query: "latest developments in AI agents",
max_results: 5,
});
result.results.forEach((r) => {
console.log(`- ${r.title}: ${r.url}`);
});
package main
import (
"context"
"fmt"
"os"
nimble "github.com/Nimbleway/nimble-go"
"github.com/Nimbleway/nimble-go/option"
"github.com/Nimbleway/nimble-go/packages/param"
)
func main() {
client := nimble.NewClient(option.WithAPIKey(os.Getenv("NIMBLE_API_KEY")))
result, err := client.Search(context.Background(), nimble.SearchParams{
Query: "latest developments in AI agents",
MaxResults: param.NewOpt(int64(5)),
})
if err != nil {
panic(err)
}
for _, r := range result.Results {
fmt.Printf("- %s: %s\n", r.Title, r.URL)
}
}
nimble search \
--query "latest developments in AI agents" \
--max-results 5
curl -X POST 'https://sdk.nimbleway.com/v2/search' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"query": "latest developments in AI agents",
"max_results": 5
}'
Extract
Get clean HTML and structured data from any URL:import os
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
result = nimble.extract.run(
url="https://www.example.com",
render=True,
formats=["html", "markdown"]
)
print(result.data.html)
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
const result = await nimble.extract.run({
url: "https://www.example.com",
render: true,
formats: ["html", "markdown"],
});
console.log(result.data?.html);
result, err := client.Extract.Run(ctx, nimble.ExtractRunParams{
URL: "https://www.example.com",
Render: nimble.ExtractRunParamsRenderUnion{OfBool: param.NewOpt(true)},
Formats: []string{"html", "markdown"},
})
if err != nil {
panic(err)
}
fmt.Println(result.Data.HTML)
nimble extract run \
--url "https://www.example.com" \
--render true \
--format html --format markdown
curl -X POST 'https://sdk.nimbleway.com/v2/extract' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://www.example.com",
"render": true,
"formats": ["html", "markdown"]
}'
Extract Template
Run pre-built extraction templates for popular sites, or create one for any website:import os
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
result = nimble.extract.templates.run(
template="amazon_pdp",
params={
"asin": "B08N5WRWNW"
}
)
parsed = result.data.parsing
print(f"Product: {parsed['product_title']}")
print(f"Price: ${parsed['web_price']}")
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
const result = await nimble.extract.templates.run({
template: "amazon_pdp",
params: {
asin: "B08N5WRWNW",
},
});
const parsed = result.data?.parsing as Record<string, any>;
console.log(`Product: ${parsed.product_title}`);
console.log(`Price: $${parsed.web_price}`);
result, err := client.Extract.Templates.Run(ctx, nimble.ExtractTemplateRunParams{
Template: "amazon_pdp",
Params: map[string]any{
"asin": "B08N5WRWNW",
},
})
if err != nil {
panic(err)
}
fmt.Println(result.Data.Parsing)
nimble extract:templates run \
--template amazon_pdp \
--params '{asin: B08N5WRWNW}'
curl -X POST 'https://sdk.nimbleway.com/v2/extract/templates/run' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"template": "amazon_pdp",
"params": {
"asin": "B08N5WRWNW"
}
}'
Map
Fast URL discovery and site structure mapping:import os
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
result = nimble.map(
url="https://www.example.com",
sitemap="include"
)
for link in result.links:
print(f"{link.title}: {link.url}")
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
const result = await nimble.map({
url: "https://www.example.com",
sitemap: "include",
});
result.links.forEach((link) => {
console.log(`${link.title}: ${link.url}`);
});
result, err := client.Map(ctx, nimble.MapParams{
URL: "https://www.example.com",
Sitemap: nimble.MapParamsSitemapInclude,
})
if err != nil {
panic(err)
}
for _, link := range result.Links {
fmt.Printf("%s: %s\n", link.Title, link.URL)
}
nimble map \
--url "https://www.example.com" \
--sitemap include
curl -X POST 'https://sdk.nimbleway.com/v2/map' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://www.example.com",
"sitemap": "include"
}'
Crawl
Extract content from entire websites:import os
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
result = nimble.crawl.run(
url="https://docs.example.com",
limit=10
)
print(f"Crawl started: {result.crawl_id}")
print(f"Status: {result.status}")
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
const result = await nimble.crawl.run({
url: "https://docs.example.com",
limit: 10,
});
console.log(`Crawl started: ${result.crawl_id}`);
console.log(`Status: ${result.status}`);
result, err := client.Crawl.Run(ctx, nimble.CrawlRunParams{
URL: "https://docs.example.com",
Limit: param.NewOpt(int64(10)),
})
if err != nil {
panic(err)
}
fmt.Println("Crawl started:", result.CrawlID)
fmt.Println("Status:", result.Status)
nimble crawl run \
--url "https://docs.example.com" \
--limit 10
curl -X POST 'https://sdk.nimbleway.com/v2/crawl' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://docs.example.com",
"limit": 10
}'
Web Search Agent
Ask a research question, get a cited answer. See the full flow in the Web Search Agent quickstart:import os, time
from nimble_python import Nimble
nimble = Nimble(api_key=os.environ["NIMBLE_API_KEY"])
run = nimble.agents.run(
input="Compare the pricing of Datadog, Grafana Cloud, and New Relic.",
)
agent_id = run.web_search_agent_id
while run.is_active:
time.sleep(10)
run = nimble.agents.runs.get(run.id, agent_id=agent_id)
result = nimble.agents.runs.result(run.id, agent_id=agent_id)
print(result.output.content)
import Nimble from "@nimble-way/nimble-js";
const nimble = new Nimble({ apiKey: process.env.NIMBLE_API_KEY });
let run = await nimble.agents.run({
input: "Compare the pricing of Datadog, Grafana Cloud, and New Relic.",
});
const agentId = run.web_search_agent_id;
while (run.is_active) {
await new Promise((r) => setTimeout(r, 10000));
run = await nimble.agents.runs.get(run.id, { agent_id: agentId });
}
const result = await nimble.agents.runs.result(run.id, { agent_id: agentId });
if ("output" in result) {
console.log(result.output.content);
}
run, err := client.Agents.Run(ctx, nimble.AgentRunParams{
Input: "Compare the pricing of Datadog, Grafana Cloud, and New Relic.",
})
if err != nil {
panic(err)
}
for run.IsActive {
time.Sleep(10 * time.Second)
polled, err := client.Agents.Runs.Get(ctx, run.ID, nimble.AgentRunGetParams{
AgentID: run.WebSearchAgentID,
})
if err != nil {
panic(err)
}
run.IsActive = polled.IsActive
}
result, err := client.Agents.Runs.Result(ctx, run.ID, nimble.AgentRunResultParams{
AgentID: run.WebSearchAgentID,
})
if err != nil {
panic(err)
}
fmt.Println(result.Output.Content.OfString)
RUN=$(nimble agents run \
--input "Compare the pricing of Datadog, Grafana Cloud, and New Relic.")
RUN_ID=$(echo "$RUN" | jq -r .id)
AGENT_ID=$(echo "$RUN" | jq -r .web_search_agent_id)
# repeat while "is_active" is true
nimble agents:runs get --agent-id "$AGENT_ID" --run-id "$RUN_ID"
# then fetch the result
nimble agents:runs result --agent-id "$AGENT_ID" --run-id "$RUN_ID"
curl -X POST 'https://sdk.nimbleway.com/v2/agents/runs' \
--header "Authorization: Bearer $NIMBLE_API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"input": "Compare the pricing of Datadog, Grafana Cloud, and New Relic."
}'
# => { "id": "task_run_...", "web_search_agent_id": "wsa_...", "status": "queued" }
# repeat while "is_active" is true
curl "https://sdk.nimbleway.com/v2/agents/$AGENT_ID/runs/$RUN_ID" \
--header "Authorization: Bearer $NIMBLE_API_KEY"
# then fetch the result
curl "https://sdk.nimbleway.com/v2/agents/$AGENT_ID/runs/$RUN_ID/result" \
--header "Authorization: Bearer $NIMBLE_API_KEY"
Next steps
Choose your integration
Plugin, MCP, SDK, or warehouse: which path fits and how each authenticates
API Reference
Full REST documentation for every endpoint
Web Search Agent
Efforts, trust reports, and use cases
Rate limits
Concurrency and throughput per plan