The U.S. Securities and Exchange Commission (SEC) provides a wealth of financial data through its EDGAR database. For developers and financial analysts, accessing this data programmatically can unlock powerful insights.
In this post, we’ll walk through a lightweight Java application designed to fetch company submission data directly from the SEC’s public APIs using Spring Boot and Spring WebFlux.
🚀 Project Overview
The goal of this project is simple: create a REST API that takes a company’s CIK (Central Index Key) and returns their filing history from the SEC.
Tech Stack:
- Java 17
- Spring Boot 3.5.8 (WebFlux for reactive programming)
- Lombok (to reduce boilerplate)
- Maven
🛠️ Implementation Details
1. The Data Model
First, we define a simple model to map the JSON response from the SEC. We use Lombok’s @Data annotation to automatically generate getters, setters, and toString method
package com.leveraon.app.sec.edgar.model;
import java.util.Map;
import lombok.Data;
@Data
public class EdgarSubmission {
private String name;
private String cik;
private Map<String, Object> filings;
}2. The Service Layer (The Core Logic)
The EdgarApiService is where the magic happens. We use Spring’s WebClient to make non-blocking HTTP requests.
Critical Detail: The SEC requires a valid
User-Agent
header in the format Sample Company Name AdminContact@<sample company domain>.com . Without this, your requests will be blocked.
@Service
public class EdgarApiService {
private final WebClient webClient;
// IMPORTANT: Replace with your actual contact info as per SEC guidelines
private static final String USER_AGENT = "Joe Doe contact@example.com";
private static final String BASE_URL = "https://data.sec.gov";
public EdgarApiService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl(BASE_URL)
.defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
.build();
}
public Mono<EdgarSubmission> getSubmissionsByCik(String cik) {
// SEC API expects CIK in a specific format, e.g., CIK0000320193.json
String urlPath = String.format("/submissions/CIK%s.json", cik);
return webClient.get()
.uri(urlPath)
.retrieve()
.bodyToMono(EdgarSubmission.class);
}
}3. The Controller
Finally, we expose the functionality via a REST controller. The endpoint returns a Mono<EdgarSubmission> adhering to reactive principles.
@RestController
@RequestMapping("/api/edgar")
public class EdgarController {
private final EdgarApiService edgarService;
public EdgarController(EdgarApiService edgarService) {
this.edgarService = edgarService;
}
@GetMapping("/submissions/{cik}")
public Mono<EdgarSubmission> getSubmissions(@PathVariable String cik) {
return edgarService.getSubmissionsByCik(cik);
}
}🏃♂️ Running the Application
To run the application, ensure you have Maven installed and run the following command in your terminal:
./mvnw spring-boot:runOnce the application is started, you can test it using curl or your browser. For example, to fetch data for Apple Inc. (CIK: 0000320193):
curl http://localhost:8080/api/edgar/submissions/0000320193💡 Key Takeaways
- Reactive by Default: Using
WebClientandMonoensures our application handles I/O efficiently, which is crucial when dealing with external APIs that might have latency. - Compliance: Respecting API usage guidelines (like the
User-Agentheader) is essential for building robust scrapers or data fetchers. - Simplicity: Spring Boot allows us to spin up a powerful integration service with just three main classes.
Happy Coding! 🚀
- Source Code (Github)

