JBrave is a modern, type-safe Java SDK for the Brave Search API. It models search queries, execution, responses, and errors as a unified lifecycle—enabling you to build, execute, inspect, and replay search interactions with strong correctness guarantees.
JBrave provides fluent builders for constructing search queries, strict validation to prevent invalid requests, and flexible execution that works with any HTTP strategy—or none at all. This makes it suitable not only for traditional backend services, but also for AI/ML pipelines, offline analysis, and deterministic testing workflows.
- ✅ Fluent, type-safe query builders with strict validation
- 🔒 Fail-fast invariants—invalid queries never reach the network
- 🔄 Flexible execution—use built-in executor or treat builders as pure
HttpRequest/URIgenerators - 🧪 Test-friendly—build and parse without network access
- 📦 Clean public API with typed error responses
- 🧠 Offline deserialization from JSON files or strings
Replace
<version>with the published release.
implementation("net.ygbstudio:jbrave:<version>")<dependency>
<groupId>net.ygbstudio</groupId>
<artifactId>jbrave</artifactId>
<version><!-- version --></version>
</dependency>JBrave can also be consumed via JitPack from GitHub releases.
A query builder represents a stateful, single-request, reusable session object. Each instance:
- Accumulates query configuration
- Stores execution results internally (HTTP response, rate limits, errors)
- Can be inspected multiple times without re-executing
- Must be explicitly reset via
reset()before reuse
Note: Query builders are not thread-safe.
This design separates query construction, execution, and result extraction, enabling custom retry logic and offline testing.
You can use them as a pure HttpRequest/URI generator with a custom HTTP client or execute them with the built-in rate-aware executor.
import net.ygbstudio.jbrave.api.builders.BraveWebQuery;
import net.ygbstudio.jbrave.api.options.*;
import net.ygbstudio.jbrave.api.filters.*;
import net.ygbstudio.jbrave.core.local.ClientInfo;
// Load token from properties file or environment variable
ClientInfo token = ClientInfo.fromProperties(
"config.properties",
"brave.subscriptionToken"
);
// Or:
// ClientInfo token = ClientInfo.fromEnvironment("BRAVE_SUBSCRIPTION_TOKEN");
// Build request
HttpRequest request = BraveWebQuery.builder()
.query("search engines")
.language(SearchLanguage.ENGLISH)
.market(MarketLocale.UNITED_STATES_ENGLISH)
.country(Country.UNITED_STATES)
.safeSearch(SafeSearch.MODERATE)
.withHeaders(req -> req
.withLatitude(37.774929)
.withLongitude(-122.419416)
.withCity("SF")
.withState("CA")
)
.withOperators(op -> op
.include("brave")
.exclude("google")
)
.count(10)
.withToken(token)
.toHttpRequest(); // Or: .toURI() / .execute()BraveWebQuery query = BraveWebQuery.builder()
.query("java http client")
.withRetries(3)
.withToken(token);
// Explicit execution
query.execute();
// or execute and get a POJO response
query.getPOJO()
.ifPresent(r -> System.out.println(
r.web().results().size()
));
// Lazy execution—extraction triggers execution automatically
Optional<WebSearchApiResponse> response = query.getPOJO();
Optional<ErrorResponse> error = query.getErrorPOJO();
// Returns either a successful response or an error response
Optional<ApiResponse> either = query.getEitherPOJO();Execution happens once per session, unless explicitly re-triggered (for example, via
execute()or after callingreset()).
After execution, inspect Brave API rate limit headers as typed objects:
query.getRateLimits()
.map(XRateLimit::limit)
.ifPresent(System.out::println);
query.getRateLimitRemaining()
.map(XRateLimitRemaining::remaining)
.ifPresent(System.out::println);
query.getRateLimitPolicy()
.map(XRateLimitPolicy::policy)
.ifPresent(System.out::println);
query.getRateLimitReset()
.map(XRateLimitReset::reset)
.ifPresent(System.out::println);All rate limit classes provide a static factory method from for deserializing data from HttpResponse headers, allowing you to implement your own HTTP client while still taking advantage of JBrave’s rate limit introspection.
Response models are decoupled from HTTP execution. Each response type also provides static factory methods for deserialization:
// From file
WebSearchApiResponse response = WebSearchApiResponse.from(new File("response.json"));
// From string
WebSearchApiResponse response = WebSearchApiResponse.from(jsonString);
// Serialize back
response.write(new File("output.json"));
String json = response.toJson();This is useful for unit tests, cached responses, offline analysis, and debugging.
| Builder | Endpoint | Response Type |
|---|---|---|
BraveWebQuery |
Web search | WebSearchApiResponse |
BraveImageQuery |
Image search | ImageSearchApiResponse |
BraveNewsQuery |
News search | NewsSearchApiResponse |
BraveVideoQuery |
Video search | VideoSearchApiResponse |
BraveSuggestQuery |
Autocomplete | SuggestSearchApiResponse |
BraveSpellcheckQuery |
Spellcheck | SpellCheckSearchApiResponse |
All builders enforce query constraints and fail fast on invalid configuration.
| Type | Purpose |
|---|---|
Country |
Geographic country codes |
MarketLocale |
Regional market identifiers |
SearchLanguage |
Language preferences |
Units |
Measurement units |
| Type | Purpose |
|---|---|
SafeSearch |
Content safety filtering |
Freshness |
Recency constraints |
ResultFilter |
Result type filtering |
| Type | Header |
|---|---|
XRateLimit |
X-RateLimit-Limit |
XRateLimitRemaining |
X-RateLimit-Remaining |
XRateLimitPolicy |
X-RateLimit-Policy |
XRateLimitReset |
X-RateLimit-Reset |
- Search-powered applications — backend services, dashboards, search gateways
- AI/ML pipelines — RAG, prompt enrichment, ranking layers, and deterministic test data; structured response fields can be parsed into embeddings, scores, or signals.
- Data collection — batch jobs, trend analysis, offline research workflows
JBrave targets publicly available Brave Search API surfaces. Some premium or plan-restricted features may be limited or omitted—only functionality that can be reliably validated is exposed.
Contributions for additional features are welcome.
⚠️ Unofficial & IndependentJBrave is an independent, community-focused Java project built around the Brave Search API. It is not affiliated with, endorsed by, or supported by Brave Software, Inc.
The library is still evolving and may introduce breaking changes.
Apache License 2.0
© 2025–2026 YGBStudio