Whisper Java SDK

Here's how to integrate the official Whisper API Java SDK into your projects. This guide provides the necessary steps for installation and a practical example to make your first API call.

Prerequisites

Installation

You can add the SDK to your project using your preferred build tool.

Maven

Add the following dependency to your project's pom.xml file:

<dependency>
  <groupId>org.openapitools</groupId>
  <artifactId>noctis-frontgraph-sdk</artifactId>
  <version>1.0.0</version>
  <scope>compile</scope>
</dependency>

Gradle

For Gradle users, add this dependency to your project's build file:

implementation 'io.github.whisper-sec:whisper-api-sdk:0.1.0'

Quick Start Example

import io.github.whispersec.*;
import io.github.whispersec.auth.*;
import io.github.whispersec.api.*;

public class QuickStart {
    public static void main(String[] args) {
        // Configure API client
        ApiClient client = new ApiClient();
        client.setBearerToken("YOUR_API_KEY");
        
        // Create API instance
        IndicatorsApi api = new IndicatorsApi(client);
        
        try {
            // Enrich an IP address
            IndicatorResponse response = api.getIndicator("ip", "8.8.8.8", null);
            System.out.println("Organization: " + response.getSummary().getOrganization());
            System.out.println("Risk Score: " + response.getReputation().getRiskScore());
        } catch (ApiException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

Core Concepts

1. API Client Architecture

The SDK is organized into three main API classes, each handling specific functionality:

  • IndicatorsApi: Enrichment and intelligence gathering
  • LocationApi: Geolocation and ASN intelligence
  • OperationsApi: Async jobs and operational security tools

2. Synchronous vs Asynchronous Operations

  • Synchronous: Direct API calls that return immediate results (e.g., single IP enrichment)
  • Asynchronous: Long-running operations that return a job ID for polling (e.g., bulk enrichment, screenshots)

3. Data Modules

When enriching indicators, you can request specific data modules:

  • routing: BGP routing information
  • rpki: RPKI validation status
  • whois: WHOIS registration data
  • dns_details: Detailed DNS records
  • ip_intelligence: IP intelligence and reputation

Authentication

Bearer Token Authentication

ApiClient client = new ApiClient();
client.setBearerToken("wsk_live_your_api_key_here");

API Overview

IndicatorsApi - Intelligence & Enrichment

The main API for gathering intelligence on IPs and domains.

Key Methods:

// Single indicator enrichment
IndicatorResponse getIndicator(String type, String value, String include)

// Historical data
HistoryResponse getIndicatorHistory(String type, String value, Integer limit)

// Infrastructure relationships
GraphResponse getIndicatorGraph(String type, String value)

// Domain subdomains
SubdomainsResponse getSubdomains(String domain, Integer limit)

// Bulk enrichment (async)
JobResponse bulkEnrichment(BulkRequest request)

// Search indicators (async)
JobResponse searchIndicators(SearchRequest request)

LocationApi - Geolocation Intelligence

Provides geographic and network location data.

Key Methods:

// Single IP geolocation
LocationResponse getIpLocation(String ip)

// Network/CIDR geolocation
LocationResponse getNetworkLocation(String network)

// Search by location attributes
List<LocationResponse> searchLocation(String field, String value, Integer limit)

// Bulk IP geolocation
BulkLocationResponse bulkGeolocate(List<String> ips)

OperationsApi - Async Jobs & Tools

Manages long-running operations and monitoring tools.

Key Methods:

// Job management
Job getJob(String jobId)
List<Job> listJobs(String status, Integer limit)

// Screenshots
JobResponse createScreenshot(ScreenshotRequest request)
ScreenshotHistory getScreenshotHistory(String target)

// Infrastructure scanning
JobResponse createInfrastructureScan(InfraScanRequest request)

// Monitoring
MonitoringStatus getMonitoringStatus(String target)
JobResponse configureMonitoringAlert(String target, AlertConfig config)

Examples

Example 1: IP Threat Assessment

public class ThreatAssessment {
    private final IndicatorsApi indicatorsApi;
    private final LocationApi locationApi;
    
    public ThreatRiskProfile assessIP(String ip) {
        ThreatRiskProfile profile = new ThreatRiskProfile();
        
        // Get comprehensive intelligence
        IndicatorResponse indicator = indicatorsApi.getIndicator(
            "ip", ip, "routing,rpki,ip_intelligence"
        );
        
        // Assess risk score
        Integer riskScore = indicator.getReputation().getRiskScore();
        profile.setRiskLevel(categorizeRisk(riskScore));
        
        // Check blacklists
        BlacklistScores blacklists = indicator.getReputation().getBlacklists();
        profile.setBlacklisted(blacklists.getTotal() > 0);
        
        // Get geolocation for geo-risk assessment
        LocationResponse location = locationApi.getIpLocation(ip);
        profile.setCountryRisk(assessCountryRisk(location.getCountry()));
        
        // Check hosting type (datacenter, residential, etc.)
        String hostingType = indicator.getNetwork().getType();
        profile.setHostingRisk(assessHostingType(hostingType));
        
        return profile;
    }
    
    private RiskLevel categorizeRisk(Integer score) {
        if (score >= 80) return RiskLevel.CRITICAL;
        if (score >= 60) return RiskLevel.HIGH;
        if (score >= 40) return RiskLevel.MEDIUM;
        if (score >= 20) return RiskLevel.LOW;
        return RiskLevel.MINIMAL;
    }
}

Example 2: Domain Investigation

public class DomainInvestigator {
    private final IndicatorsApi api;
    
    public DomainReport investigate(String domain) {
        DomainReport report = new DomainReport();
        
        // Get domain intelligence with WHOIS
        IndicatorResponse domainInfo = api.getIndicator(
            "domain", domain, "whois,dns_details"
        );
        
        // Extract registration details
        WhoisInfo whois = domainInfo.getWhois();
        report.setRegistrar(whois.getRegistrar());
        report.setCreatedDate(whois.getCreatedDate());
        report.setExpiryDate(whois.getExpiryDate());
        report.setRegistrant(whois.getRegistrantName());
        
        // Get all subdomains
        SubdomainsResponse subdomains = api.getSubdomains(domain, 1000);
        report.setSubdomainCount(subdomains.getTotal());
        report.setActiveSubdomains(filterActiveSubdomains(subdomains));
        
        // Find similar domains (typosquatting detection)
        JobResponse similarJob = api.generateSimilarDomainsPost(
            domain,
            new SimilarDomainsRequest()
                .type("typo")
                .limit(100)
        );
        
        // Get infrastructure relationships
        GraphResponse graph = api.getIndicatorGraph("domain", domain);
        report.setRelatedIPs(graph.getRelatedIPs());
        report.setRelatedDomains(graph.getRelatedDomains());
        
        return report;
    }
}

Error Handling

Exception Hierarchy

ApiException (base exception)
├── ApiClientException (client-side errors)
├── ApiServerException (server-side errors)
├── RateLimitException (429 errors)
└── AuthenticationException (401 errors)

Error Handling Example

public class ErrorHandler {
    private static final int MAX_RETRIES = 3;
    
    public <T> T executeWithRetry(Supplier<T> operation) {
        int attempts = 0;
        Exception lastException = null;
        
        while (attempts < MAX_RETRIES) {
            try {
                return operation.get();
            } catch (RateLimitException e) {
                // Handle rate limiting with exponential backoff
                long retryAfter = e.getRetryAfterSeconds();
                System.out.println("Rate limited. Retrying after " + retryAfter + " seconds");
                sleepSeconds(retryAfter);
            } catch (ApiServerException e) {
                // Retry on server errors (5xx)
                if (e.getErrorCode() >= 500) {
                    System.out.println("Server error. Attempt " + (attempts + 1));
                    sleepSeconds(Math.pow(2, attempts));
                } else {
                    throw e; // Don't retry client errors
                }
            } catch (AuthenticationException e) {
                // Authentication errors should not be retried
                System.err.println("Authentication failed: " + e.getMessage());
                throw e;
            } catch (ApiException e) {
                // Log and handle other API errors
                System.err.println("API Error: " + e.getMessage());
                lastException = e;
            }
            attempts++;
        }
        
        throw new RuntimeException("Max retries exceeded", lastException);
    }
    
    private void sleepSeconds(double seconds) {
        try {
            Thread.sleep((long)(seconds * 1000));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

Support and Resources