Tutorials & SDKs
Java Integration
Use Hive from JVM services with Java HttpClient. This guide covers bearer authentication, REST execution, tool discovery, structured error handling, and reusable client code for services that need live crypto prices, wallet data, DeFi analytics, and token security.
Requirements: Java 11+
Dependencies
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
Quick Start
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
public class HiveExample {
private static final String BASE_URL = "https://mcp.hiveintelligence.xyz";
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("HIVE_API_KEY");
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> payload = Map.of(
"tool", "get_price",
"args", Map.of("ids", "bitcoin", "vs_currencies", "usd")
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/api/v1/execute"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + apiKey)
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(payload)))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
Reusable Client
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;
public class HiveClient {
private final String baseUrl;
private final String apiKey;
private final HttpClient httpClient;
private final ObjectMapper objectMapper;
public HiveClient(String apiKey) {
this.baseUrl = "https://mcp.hiveintelligence.xyz";
this.apiKey = apiKey;
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.build();
this.objectMapper = new ObjectMapper();
}
public Map<String, Object> execute(String tool, Map<String, Object> args) throws Exception {
Map<String, Object> payload = Map.of(
"tool", tool,
"args", args
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/api/v1/execute"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + apiKey)
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(payload)))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 300) {
throw new RuntimeException("Hive request failed: " + response.body());
}
return objectMapper.readValue(response.body(), Map.class);
}
}
Discovery
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://mcp.hiveintelligence.xyz/api/v1/tools?limit=50"))
.header("Authorization", "Bearer " + System.getenv("HIVE_API_KEY"))
.GET()
.build();
Example Calls
HiveClient client = new HiveClient(System.getenv("HIVE_API_KEY"));
Map<String, Object> market = client.execute("get_coins_market_data", Map.of(
"vs_currency", "usd",
"order", "market_cap_desc",
"per_page", 5
));
Map<String, Object> wallet = client.execute("moralis_get_wallet_net_worth", Map.of(
"address", "0x1234...",
"chain", "eth"
));
Map<String, Object> prediction = client.execute("codex_prediction_markets", Map.of(
"networkId", 1
));
Error Handling
Hive returns a JSON envelope on every response. Non-2xx bodies carry a structured error object — parse it before retrying:
import com.fasterxml.jackson.databind.JsonNode;
public class HiveException extends RuntimeException {
public final int httpStatus;
public final String code;
public HiveException(int httpStatus, String code, String message) {
super(code + ": " + message);
this.httpStatus = httpStatus;
this.code = code;
}
}
private Map<String, Object> executeWithRetry(String tool, Map<String, Object> args, int maxRetries)
throws Exception {
Exception last = null;
for (int attempt = 0; attempt < maxRetries; attempt++) {
try {
HttpResponse<String> response = httpClient.send(buildRequest(tool, args),
HttpResponse.BodyHandlers.ofString());
int status = response.statusCode();
if (status == 429) {
long retryAfter = response.headers().firstValueAsLong("Retry-After").orElse(1L << attempt);
Thread.sleep(retryAfter * 1000L);
continue;
}
if (status >= 500) {
Thread.sleep(1000L * (1L << attempt));
continue;
}
if (status >= 400) {
JsonNode body = objectMapper.readTree(response.body());
throw new HiveException(status,
body.path("error").path("code").asText("unknown"),
body.path("error").path("message").asText(response.body()));
}
return objectMapper.readValue(response.body(), Map.class);
} catch (java.io.IOException | InterruptedException exc) {
last = exc;
Thread.sleep(1000L * (1L << attempt));
}
}
throw new HiveException(0, "exhausted_retries", "All retries failed: " + last);
}
Key HTTP codes to handle:
- 400 — invalid tool name or args.
- 401 — missing or invalid API key. Rotate via the dashboard; don't retry.
- 429 — rate-limited. Honor
Retry-After; exponential backoff otherwise. - 502 / 503 — upstream provider failure. Exponential backoff.
Async with CompletableFuture
For fan-out patterns (daily briefings, concurrent wallet profiles) use sendAsync:
import java.util.concurrent.CompletableFuture;
import java.util.List;
public CompletableFuture<JsonNode> executeAsync(String tool, Map<String, Object> args) throws Exception {
HttpRequest request = buildRequest(tool, args);
return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(response -> {
if (response.statusCode() >= 300) {
throw new RuntimeException("Hive call failed: " + response.body());
}
try {
return objectMapper.readTree(response.body());
} catch (Exception exc) {
throw new RuntimeException(exc);
}
});
}
// Fan out 3 concurrent tool calls for a market brief
HiveClient client = new HiveClient(System.getenv("HIVE_API_KEY"));
CompletableFuture<JsonNode> prices = client.executeAsync("get_price", Map.of(
"ids", "bitcoin,ethereum", "vs_currencies", "usd"));
CompletableFuture<JsonNode> tvl = client.executeAsync("get_protocol_tvl", Map.of());
CompletableFuture<JsonNode> oi = client.executeAsync("get_open_interest", Map.of("exchange", "binance"));
CompletableFuture.allOf(prices, tvl, oi).join();
System.out.println("Brief assembled: " + prices.get() + tvl.get() + oi.get());
Hive bills one credit per tool call regardless of concurrency, so fan-out is the right default for research and reporting agents.
Tool Discovery
Prefer runtime discovery over hardcoded schemas — new tools show up automatically as Hive ships providers:
public List<JsonNode> discover(String search) throws Exception {
List<JsonNode> items = new java.util.ArrayList<>();
String cursor = null;
while (true) {
StringBuilder url = new StringBuilder(baseUrl).append("/api/v1/tools?limit=200");
if (cursor != null) url.append("&cursor=").append(cursor);
if (search != null) url.append("&search=").append(search);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url.toString()))
.header("Authorization", "Bearer " + apiKey)
.GET().build();
JsonNode page = objectMapper.readTree(
httpClient.send(request, HttpResponse.BodyHandlers.ofString()).body());
page.path("data").forEach(items::add);
JsonNode nextCursor = page.path("meta").path("cursor");
if (nextCursor.isMissingNode() || nextCursor.isNull()) return items;
cursor = nextCursor.asText();
}
}
List<JsonNode> walletTools = client.discover("wallet");
Spring Boot Integration
If you run on Spring, register the client as a singleton bean and inject it into services:
@Configuration
public class HiveConfig {
@Bean
public HiveClient hiveClient(@Value("${hive.api.key}") String apiKey) {
return new HiveClient(apiKey);
}
}
@Service
public class MarketIntelService {
private final HiveClient hive;
public MarketIntelService(HiveClient hive) {
this.hive = hive;
}
public Map<String, Object> briefing() throws Exception {
return hive.execute("get_price",
Map.of("ids", "bitcoin,ethereum,solana", "vs_currencies", "usd"));
}
}
Use Spring's @Retryable or Resilience4j for retry policy instead of hand-rolled loops.
Notes
- The current REST payload keys are
toolandargs. OldertoolName/argumentsexamples are legacy. - Use
GET /api/v1/toolsfor live schemas and tool discovery; never hardcode definitions. - Failed 4xx calls do not consume credits; 5xx server errors are refunded.
- Every response carries a
fetched_attimestamp agents can use to reason about staleness.