Search API

POST /v1/search

Search the web and vertical data sources through one endpoint. General search only needs query. For a vertical capability, discover its tag and parameter definitions first. The gateway routes the request, combines sources and reranks results.

Request examples

General search

Submit query. The gateway routes the request, combines sources and reranks results.

cURL

cURL · macOS / Linux / Git Bash

curl -X POST https://api.anysearch.com/v1/search \
  -H "Authorization: Bearer YOUR_ANYSEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "Global AI Semiconductor Industry Analysis",
  "max_results": 5
}'

Python

Python 3 · requests

import os
import requests

response = requests.post(
    "https://api.anysearch.com/v1/search",
    headers={
        "Authorization": f"Bearer {os.environ['ANYSEARCH_API_KEY']}",
    },
    json={
        "query": "Global AI Semiconductor Industry Analysis",
        "max_results": 5,
    },
    timeout=30,
)

if not response.ok:
    request_id = response.headers.get("X-Request-ID", "unknown")
    raise RuntimeError(
        f"Request failed: HTTP {response.status_code}; request_id={request_id}"
    )

result = response.json()
print(result["data"])

JavaScript

JavaScript · Node.js 18+

const response = await fetch("https://api.anysearch.com/v1/search", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ANYSEARCH_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    query: "Global AI Semiconductor Industry Analysis",
    max_results: 5,
  }),
  signal: AbortSignal.timeout(30_000),
});

if (!response.ok) {
  const requestId = response.headers.get("X-Request-ID") ?? "unknown";
  throw new Error(
    `Request failed: HTTP ${response.status}; request_id=${requestId}`
  );
}

const result = await response.json();
console.log(result.data);

Go

Go · Standard library

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	req, err := http.NewRequest(
		http.MethodPost,
		"https://api.anysearch.com/v1/search",
		strings.NewReader(`{
			"query": "Global AI Semiconductor Industry Analysis",
			"max_results": 5
		}`),
	)
	if err != nil {
		panic(err)
	}

	req.Header.Set("Authorization", "Bearer "+os.Getenv("ANYSEARCH_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		requestID := resp.Header.Get("X-Request-ID")
		if requestID == "" {
			requestID = "unknown"
		}

		panic(fmt.Sprintf(
			"Request failed: HTTP %d; request_id=%s",
			resp.StatusCode, requestID,
		))
	}

	var result struct {
		Data json.RawMessage `json:"data"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		panic(err)
	}

	fmt.Println(string(result.Data))
}

Rust

Rust · reqwest + serde_json

use reqwest::blocking::Client;
use serde_json::{json, Value};
use std::{env, error::Error, time::Duration};

fn main() -> Result<(), Box<dyn Error>> {
    let api_key = env::var("ANYSEARCH_API_KEY")?;

    let client = Client::builder()
        .timeout(Duration::from_secs(30))
        .build()?;

    let response = client
        .post("https://api.anysearch.com/v1/search")
        .bearer_auth(api_key)
        .json(&json!({
            "query": "Global AI Semiconductor Industry Analysis",
            "max_results": 5,
        }))
        .send()?;

    if !response.status().is_success() {
        let request_id = response
            .headers()
            .get("X-Request-ID")
            .and_then(|value| value.to_str().ok())
            .unwrap_or("unknown");

        return Err(format!(
            "Request failed: HTTP {}; request_id={request_id}",
            response.status()
        )
        .into());
    }

    let result: Value = response.json()?;
    println!("{}", result["data"]);

    Ok(())
}

Vertical search

Use the discovered finance.quote capability and its required type: "stock" parameter.

cURL

cURL · macOS / Linux / Git Bash

curl -X POST https://api.anysearch.com/v1/search \
  -H "Authorization: Bearer YOUR_ANYSEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "Apple stock price",
  "tag": "finance.quote",
  "params": {
    "type": "stock"
  },
  "max_results": 5
}'

Python

Python 3 · requests

# Install: pip install requests
import os
import requests

payload = {
  "query": "Apple stock price",
  "tag": "finance.quote",
  "params": {
    "type": "stock"
  },
  "max_results": 5
}
response = requests.post(
    "https://api.anysearch.com/v1/search",
    headers={
        "Authorization": "Bearer " + os.environ["ANYSEARCH_API_KEY"],
    },
    json=payload,
    timeout=30,
)
if not response.ok:
    # Do not log the response body: HTTP 402 may contain credentials.
    print({"status": response.status_code,
           "request_id": response.headers.get("X-Request-ID")})
    raise SystemExit(1)
result = response.json()
print(result["data"])

JavaScript

JavaScript · Node.js 18+

// Node.js 18+; set ANYSEARCH_API_KEY before running.
const response = await fetch("https://api.anysearch.com/v1/search", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.ANYSEARCH_API_KEY,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "query": "Apple stock price",
    "tag": "finance.quote",
    "params": {
      "type": "stock"
    },
    "max_results": 5
  }),
  signal: AbortSignal.timeout(30_000)
});
if (!response.ok) {
  // Do not log the response body: HTTP 402 may contain credentials.
  throw new Error("HTTP " + response.status +
    "; request_id=" + response.headers.get("X-Request-ID"));
}
const result = await response.json();
console.log(result.data);

Go

Go · Standard library

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    if err := run(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

func run() error {
    key := os.Getenv("ANYSEARCH_API_KEY")
    if key == "" {
        return fmt.Errorf("set ANYSEARCH_API_KEY before running")
    }
    payload := strings.NewReader(`{
  "query": "Apple stock price",
  "tag": "finance.quote",
  "params": {
    "type": "stock"
  },
  "max_results": 5
}`)
    request, err := http.NewRequest("POST", "https://api.anysearch.com/v1/search", payload)
    if err != nil {
        return err
    }
    request.Header.Set("Authorization", "Bearer " + key)
    request.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 30 * time.Second}
    response, err := client.Do(request)
    if err != nil {
        return err
    }
    defer response.Body.Close()
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        // HTTP 402 bodies may contain credentials; keep them out of logs.
        return fmt.Errorf("HTTP %d; request_id=%s",
            response.StatusCode, response.Header.Get("X-Request-ID"))
    }
    var result map[string]json.RawMessage
    if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
        return err
    }
    fmt.Println(string(result["data"]))
    return nil
}

Rust

Rust · reqwest + serde_json

// Dependencies:
// cargo add reqwest --features blocking,json
// cargo add serde_json
use reqwest::blocking::Client;
use serde_json::{json, Value};
use std::{env, error::Error, time::Duration};

fn main() -> Result<(), Box<dyn Error>> {
    let key = env::var("ANYSEARCH_API_KEY")?;
    let client = Client::builder()
        .timeout(Duration::from_secs(30))
        .build()?;
    let response = client
        .post("https://api.anysearch.com/v1/search")
        .bearer_auth(key)
        .json(&json!({
          "query": "Apple stock price",
          "tag": "finance.quote",
          "params": {
            "type": "stock"
          },
          "max_results": 5
        }))
        .send()?;
    if !response.status().is_success() {
        // HTTP 402 bodies may contain credentials; keep them out of logs.
        let request_id = response.headers().get("X-Request-ID")
            .and_then(|value| value.to_str().ok()).unwrap_or("unknown");
        return Err(format!("HTTP {}; request_id={}",
            response.status(), request_id).into());
    }
    let result: Value = response.json()?;
    println!("{}", result["data"]);
    Ok(())
}

Authentication and example environment

Examples use Authorization: Bearer YOUR_ANYSEARCH_API_KEY. Python, JavaScript, Go and Rust read the ANYSEARCH_API_KEY environment variable. cURL uses Bash syntax; use Git Bash or WSL on Windows. Code timeouts are client-side only.

Using tag and params

Find a capability by tag, purpose or parameter name →

ItemHow to fill it
tagUse one complete tag, not only its domain.
paramsUse a JSON object with parameter names defined by that tag. Omit it if there are no dedicated parameters.
Required and conditional parametersRead both required flags and descriptions. required=false can still have a conditional requirement.
Types, allowed values and defaultsThe definitions provide description, required and optional sort_order. Do not infer separate schema fields.
ApplicabilityRespect upstream-specific, summary-only and future-filter limitations.

A minimal general search can omit tag and only submit query.

When to include tag and params

ScenariotagparamsFlow
General searchOmitOmitSubmit query for intent-based routing.
Specific vertical capabilityUse a discovered sub_domainFollow its definitionDiscover → read parameters → search.

Request parameters

ParameterTypeRequiredDefaultDescription
querystringRequired—A non-empty search query.
max_resultsintOptional10Number of results, from 1 to 10.
tagstringOptional—One complete capability tag in {domain}.{sub_domain} form. Read it from the capability directory or discovery response.
zonestringOptional—Region: cn or intl.
languagestringOptional—Preferred language, such as zh-CN or en.
paramsobjectOptional—Capability-specific parameters. Follow the returned names, descriptions and required flags.
formatstringOptional—json or markdown. Markdown changes result content; the outer response is still JSON.

— means no documented default or not applicable.

Response fields

Markdown content

format: "markdown" changes data.results[].content; the outer response remains JSON.

FieldDescription
data.resultsArray of search results.
data.results[].titleAlways present; can be an empty string if the source has no title.
data.results[].urlSource URL.
data.results[].snippetSummary; omitted if unavailable.
data.results[].contentCleaned content; omitted if unavailable.
data.metadata.total_resultsActual number of returned results.
data.metadata.search_time_msUpstream search time in milliseconds.

Success response · Illustrative content and values

{
  "code": 0,
  "message": "success",
  "request_id": "7d6f4e91-2a83-4c5b-9f10-6e8a3d27b541",
  "data": {
    "results": [
      {
        "title": "Example source",
        "url": "https://example.com/article",
        "snippet": "A short source summary.",
        "content": "Cleaned page content for the example."
      }
    ],
    "metadata": {
      "total_results": 1,
      "search_time_ms": 312
    }
  }
}

Error codes

HTTP status codes and their meanings. error_code is optional; inspect the actual response.

HTTP statusMeaning
400Invalid request body or fields, missing query, or an upstream client error.
401Invalid Authorization or API Key.
402Quota exhausted. An anonymous request may receive generated credentials in message.
403API Key expired, account disabled, or access forbidden.
415Missing Content-Type or a value other than application/json.
429API Key, user, or anonymous IP rate limit exceeded.
502Search service unavailable or an invalid upstream response.

400 · Missing query

{
  "code": -1,
  "message": "Query is required.",
  "request_id": "7d6f4e91-2a83-4c5b-9f10-6e8a3d27b541"
}

Anonymous quota response

When an anonymous request exceeds the daily free quota, the rejected request is not executed. After automatic account creation completes, the multi-line HTTP 402 message can contain a username, password and API Key. Account creation may briefly still be in progress. Once complete credentials are available, use the Bearer API Key to resubmit the original request.

402 · Redacted structural example

{
  "code": -1,
  "message": "Your account and API key have been automatically generated. Use the API key below to continue.\nusername=<USERNAME>\npassword=<PASSWORD>\napi_key=<API_KEY>",
  "request_id": "7d6f4e91-2a83-4c5b-9f10-6e8a3d27b541"
}

Responses may contain credentials

HTTP 402 may contain a password and API Key. Do not pass the raw response to routine logs, analytics, tracing, tickets or model context. Retain only the HTTP status and request_id for diagnostics.

FAQ

Is tag required?

No. General search only needs query. Discover a vertical capability before specifying its tag and parameters.

Can snippet or content be missing?

Yes. Both fields can be omitted if unavailable. Clients should handle missing values.

Documentation navigation