🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Brave Search

by @byungkyu

Brave Search API integration with managed authentication. Search the web, images, news, and videos with privacy-focused search. Use this skill when users wan...

Versionv1.0.1
Downloads1,516
TERMINAL
clawhub install brave-search-api

πŸ“– About This Skill


name: brave-search description: | Brave Search API integration with managed authentication. Search the web, images, news, and videos with privacy-focused search. Use this skill when users want to search the web, find images, get news, or search videos using Brave Search. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). compatibility: Requires network access and valid Maton API key metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 homepage: "https://maton.ai" requires: env: - MATON_API_KEY

Brave Search

Access the Brave Search API with managed authentication. Search the web, images, news, and videos with a privacy-focused search engine.

Quick Start

# Web search
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=python+programming&count=5')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://api.maton.ai/brave-search/{native-api-path}

Maton proxies requests to api.search.brave.com and automatically injects your API key.

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

1. Sign in or create an account at maton.ai 2. Go to maton.ai/settings 3. Copy your API key

Connection Management

Manage your Brave Search connections at https://api.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=brave-search&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'brave-search'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "{connection_id}",
    "status": "ACTIVE",
    "creation_time": "2026-03-10T11:12:30.963141Z",
    "last_updated_time": "2026-03-10T11:13:55.282885Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "brave-search",
    "metadata": {},
    "method": "API_KEY"
  }
}

Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Brave Search connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=test')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If you have multiple connections, always include this header to ensure requests go to the intended account.

Security & Permissions

  • Access is scoped to web search, news search, image search, and AI-powered summaries within the connected Brave Search account.
  • All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
  • API Reference

    Web Search

    GET /brave-search/res/v1/web/search?q={query}
    

    Required Parameters:

  • q (string): Search query (1-400 characters, max 50 words)
  • Optional Parameters:

  • country (string): 2-letter country code (default: "US")
  • search_lang (string): Search language code (default: "en")
  • ui_lang (string): UI language in RFC 9110 format (default: "en-US")
  • count (integer): Results per page, 1-20 (default: 20)
  • offset (integer): Page offset, 0-9 (default: 0)
  • safesearch (string): Filter level - "off", "moderate", "strict" (default: "moderate")
  • freshness (string): Time filter - "pd" (past day), "pw" (past week), "pm" (past month), "py" (past year), or date range
  • text_decorations (boolean): Include highlighting markers (default: true)
  • result_filter (string): Comma-separated result types (discussions, faq, infobox, news, videos, web)
  • extra_snippets (boolean): Get up to 5 alternative excerpts
  • summary (boolean): Enable summarizer
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=machine+learning&count=10&freshness=pw')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "search",
      "query": {
        "original": "machine learning",
        "show_strict_warning": false,
        "is_navigational": false,
        "country": "us",
        "more_results_available": true
      },
      "web": {
        "type": "search",
        "results": [
          {
            "title": "Machine Learning - Wikipedia",
            "url": "https://en.wikipedia.org/wiki/Machine_learning",
            "description": "Machine learning is a subset of artificial intelligence...",
            "language": "en",
            "family_friendly": true
          }
        ]
      },
      "discussions": {...},
      "faq": {...},
      "videos": {...}
    }
    

    Image Search

    GET /brave-search/res/v1/images/search?q={query}
    

    Required Parameters:

  • q (string): Search query
  • Optional Parameters:

  • country (string): 2-letter country code
  • search_lang (string): Search language code
  • count (integer): Results per page, 1-20
  • safesearch (string): Filter level - "off", "moderate", "strict"
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/images/search?q=sunset&count=5')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "images",
      "results": [
        {
          "title": "Beautiful Sunset",
          "url": "https://example.com/sunset.jpg",
          "source": "https://example.com/gallery",
          "thumbnail": {
            "src": "https://imgs.search.brave.com/..."
          },
          "properties": {
            "width": 1920,
            "height": 1080,
            "format": "jpeg"
          }
        }
      ]
    }
    

    News Search

    GET /brave-search/res/v1/news/search?q={query}
    

    Required Parameters:

  • q (string): Search query
  • Optional Parameters:

  • country (string): 2-letter country code
  • search_lang (string): Search language code
  • count (integer): Results per page, 1-20
  • freshness (string): Time filter - "pd", "pw", "pm", "py"
  • safesearch (string): Filter level
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/news/search?q=technology&count=5&freshness=pd')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "news",
      "results": [
        {
          "title": "Latest Tech News",
          "url": "https://example.com/news/tech",
          "description": "Breaking technology news...",
          "age": "2 hours ago",
          "source": {
            "name": "Tech News",
            "url": "https://technews.com"
          },
          "thumbnail": {
            "src": "https://imgs.search.brave.com/..."
          }
        }
      ]
    }
    

    Video Search

    GET /brave-search/res/v1/videos/search?q={query}
    

    Required Parameters:

  • q (string): Search query
  • Optional Parameters:

  • country (string): 2-letter country code
  • search_lang (string): Search language code
  • count (integer): Results per page, 1-20
  • safesearch (string): Filter level
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/videos/search?q=tutorial&count=5')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "videos",
      "results": [
        {
          "title": "Python Tutorial for Beginners",
          "url": "https://www.youtube.com/watch?v=...",
          "description": "Learn Python programming...",
          "age": "1 year ago",
          "duration": "3:45:00",
          "thumbnail": {
            "src": "https://imgs.search.brave.com/..."
          },
          "meta_url": {
            "hostname": "www.youtube.com"
          }
        }
      ]
    }
    

    Local POIs

    GET /brave-search/res/v1/local/pois?ids={poi_ids}
    

    Get details about local points of interest by their IDs (obtained from web search results).

    Required Parameters:

  • ids (string): Comma-separated POI IDs
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/local/pois?ids=poi_123,poi_456')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "local_pois",
      "results": [
        {
          "id": "poi_123",
          "name": "Coffee Shop",
          "address": "123 Main St",
          "phone": "+1-555-1234",
          "rating": 4.5,
          "reviews": 128
        }
      ]
    }
    

    POI Descriptions

    GET /brave-search/res/v1/local/descriptions?ids={poi_ids}
    

    Get detailed descriptions for local points of interest.

    Required Parameters:

  • ids (string): Comma-separated POI IDs
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/local/descriptions?ids=poi_123')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "local_descriptions",
      "results": [
        {
          "id": "poi_123",
          "description": "A cozy coffee shop known for artisanal brews..."
        }
      ]
    }
    

    Autosuggest

    > Note: Requires Autosuggest subscription plan.

    GET /brave-search/res/v1/suggest/search?q={query}
    

    Get search suggestions as users type.

    Required Parameters:

  • q (string): Partial search query
  • Optional Parameters:

  • country (string): 2-letter country code
  • count (integer): Number of suggestions to return
  • rich (boolean): Enable enhanced metadata
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/suggest/search?q=how+to&count=5&rich=true')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "suggest",
      "query": {
        "original": "how to"
      },
      "results": [
        {
          "query": "how to learn python",
          "is_entity": false
        },
        {
          "query": "how to code",
          "is_entity": false
        }
      ]
    }
    

    Spellcheck

    > Note: Requires Spellcheck subscription plan.

    GET /brave-search/res/v1/spellcheck/search?q={query}
    

    Check spelling and get corrections.

    Required Parameters:

  • q (string): Query to check for spelling errors
  • country (string): Country code for localized corrections
  • Example:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/spellcheck/search?q=helo+wrold&country=US')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Response:

    {
      "type": "spellcheck",
      "query": {
        "original": "helo wrold"
      },
      "results": [
        {
          "query": "hello world"
        }
      ]
    }
    

    Summarizer

    > Note: Requires Summarizer subscription plan.

    First, perform a web search with summary=1 to get a summarizer key, then use that key to fetch the summary.

    #### Get Summarizer Key

    GET /brave-search/res/v1/web/search?q={query}&summary=1
    

    #### Fetch Summary

    GET /brave-search/res/v1/summarizer/search?key={summarizer_key}
    

    Optional Parameters:

  • entity_info (boolean): Include entity details
  • inline_references (boolean): Include citation markers
  • Example:

    python <<'EOF'
    import urllib.request, os, json

    Step 1: Get summarizer key from web search

    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=what+is+python&summary=1') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') data = json.load(urllib.request.urlopen(req)) summarizer_key = data.get('summarizer', {}).get('key')

    Step 2: Fetch summary using the key

    if summarizer_key: req = urllib.request.Request(f'https://api.maton.ai/brave-search/res/v1/summarizer/search?key={summarizer_key}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF

    #### Additional Summarizer Endpoints

    GET /brave-search/res/v1/summarizer/summary?key={key}           # Summary only
    GET /brave-search/res/v1/summarizer/title?key={key}             # Title only
    GET /brave-search/res/v1/summarizer/enrichments?key={key}       # Enrichment data
    GET /brave-search/res/v1/summarizer/followups?key={key}         # Follow-up suggestions
    GET /brave-search/res/v1/summarizer/entity_info?key={key}       # Entity information
    

    Pagination

    Use count and offset for pagination:

    # First page (results 1-10)
    GET /brave-search/res/v1/web/search?q=test&count=10&offset=0

    Second page (results 11-20)

    GET /brave-search/res/v1/web/search?q=test&count=10&offset=1

    Note: offset ranges from 0-9, giving access to up to 200 results (20 results Γ— 10 pages).

    Check query.more_results_available in the response to determine if more results exist.

    Location Headers

    For location-aware results, include location headers:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=restaurants+near+me&count=10')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    req.add_header('x-loc-lat', '37.7749')
    req.add_header('x-loc-long', '-122.4194')
    req.add_header('x-loc-city', 'San Francisco')
    req.add_header('x-loc-state', 'CA')
    req.add_header('x-loc-country', 'US')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Available Location Headers:

  • x-loc-lat: Latitude (-90 to 90)
  • x-loc-long: Longitude (-180 to 180)
  • x-loc-timezone: IANA timezone identifier
  • x-loc-city: City name
  • x-loc-state: State/province
  • x-loc-country: 2-letter country code
  • x-loc-postal-code: ZIP/postal code
  • Code Examples

    JavaScript

    const response = await fetch(
      'https://api.maton.ai/brave-search/res/v1/web/search?q=javascript&count=10',
      {
        headers: {
          'Authorization': Bearer ${process.env.MATON_API_KEY}
        }
      }
    );
    const data = await response.json();
    console.log(data.web.results);
    

    Python

    import os
    import requests

    response = requests.get( 'https://api.maton.ai/brave-search/res/v1/web/search', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, params={'q': 'python programming', 'count': 10} ) data = response.json() for result in data.get('web', {}).get('results', []): print(f"{result['title']}: {result['url']}")

    Notes

  • Maximum 20 results per request
  • Maximum 10 pages of results (offset 0-9)
  • Query length: 1-400 characters, max 50 words
  • Brave Search is privacy-focused and doesn't track users
  • Results include multiple types: web, news, videos, discussions, FAQ, infobox
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments
  • Error Handling

    | Status | Meaning | |--------|---------| | 400 | Missing Brave Search connection | | 401 | Invalid or missing Maton API key | | 404 | Subscription not found | | 422 | Invalid subscription token | | 429 | Rate limited or quota exceeded | | 4xx/5xx | Passthrough error from Brave Search API |

    Troubleshooting: API Key Issues

    1. Check that the MATON_API_KEY environment variable is set:

    echo $MATON_API_KEY
    

    2. Verify the API key is valid by listing connections:

    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/connections')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    Troubleshooting: Invalid App Name

    1. Ensure your URL path starts with brave-search. For example:

  • Correct: https://api.maton.ai/brave-search/res/v1/web/search?q=test
  • Incorrect: https://api.maton.ai/res/v1/web/search?q=test
  • Resources

  • Brave Search API Documentation
  • Brave Search API Dashboard
  • Maton Community
  • Maton Support
  • πŸ’‘ Examples

    # Web search
    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.maton.ai/brave-search/res/v1/web/search?q=python+programming&count=5')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
    EOF
    

    πŸ“‹ Tips & Best Practices

  • Maximum 20 results per request
  • Maximum 10 pages of results (offset 0-9)
  • Query length: 1-400 characters, max 50 words
  • Brave Search is privacy-focused and doesn't track users
  • Results include multiple types: web, news, videos, discussions, FAQ, infobox
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments