Design & media

Brave Search

Try it

Search the web, images, news, and videos via the Brave Search API with managed authentication.

What it does

Provides access to the Brave Search API through a managed proxy. Requests are sent to the Maton gateway with a Bearer API key in the Authorization header, and the proxy forwards them to api.search.brave.com while injecting the underlying credential. Web, image, news, and video search are supported, with parameters for country, language, result count, safesearch, and time filtering. Additional endpoints cover local POI lookups, POI descriptions, autosuggest, and spellcheck. Connections can be listed, created, fetched, and deleted through the gateway, and any write operation requires explicit user confirmation before it runs.

When to use it

  • Run a web search with country, language, and freshness filters
  • Find images or videos on a topic
  • Pull recent news articles for a keyword
  • Look up local POI details from Brave Search place IDs

The skill document

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

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": {...}
}
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"
      }
    }
  ]
}
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/..."
      }
    }
  ]
}
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

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

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. 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

Related skills

Connect to Google Search Console via a managed OAuth proxy to query search analytics, manage sitemaps, and inspect site performance.

265 installs10 stars

Search the web, extract page content, crawl sites, and run research tasks through the Tavily API via the Maton gateway.

30 installs

Search the web, fetch page contents, and run async research through the Exa API with managed key authentication.

26 installs

Call the Firecrawl API for scraping, crawling, URL mapping, and web search with managed authentication.

95 installs1 stars

Local web search skill that runs entirely on the user's machine. Scrapes DuckDuckGo / Bing / Google HTML directly with automatic engine fallback (DDG -> Bing...

1 installs1 stars

Access Dropbox files, folders, and metadata through the Maton gateway with managed OAuth.

170 installs5 stars