Goodjobsfirst APIviolationtracker.goodjobsfirst.org ↗
Access Good Jobs First Violation Tracker data via API. Search 3,400+ parent companies, filter by agency, year, and penalty. Get violation details and summaries.
What is the Goodjobsfirst API?
This API exposes 6 endpoints covering corporate regulatory violation records from Good Jobs First's Violation Tracker, a database of enforcement actions dating back to 2000. The search_violations endpoint lets you query records by company name, agency, year, case type, and penalty range. Each violation record includes fields like penalty_amount, primary_offense_type, agency, and current_parent, and reference endpoints list all 3,400+ parent companies and every tracked federal agency.
curl -X GET 'https://api.parse.bot/scraper/bd06de44-0e3a-452b-baf0-8df937e4644d/search_violations?page=1&sort=penalty_amount&year=2020&order=asc&pen_op=gt&company=exxon&company_op=starts' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace violationtracker-goodjobsfirst-org-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Violation Tracker SDK — search violations, drill into details, explore agencies."""
from parse_apis.violation_tracker_api import ViolationTracker, CompanyMatchOp, Sort, ViolationNotFound
client = ViolationTracker()
# Search for Exxon violations by company name, capped to 5 results.
for v in client.violationsummaries.search(company="exxon", company_op=CompanyMatchOp.STARTS, limit=5):
print(v.company, v.penalty_amount, v.year)
# Drill down: take one violation summary and fetch its full detail.
result = client.violationsummaries.search(company="exxon", limit=1).first()
if result:
detail = result.details()
print(detail.company, detail.penalty, detail.violation_description)
# List agencies and get the first one's summary.
agency = client.agencies.list(limit=1).first()
if agency:
agency_summary = agency.summary()
print(agency_summary.summary.agency_name, agency_summary.summary.penalty_total_since_2000)
# Get a parent company summary by constructing from a known slug.
parent = client.parent("exxon-mobil")
try:
parent_summary = parent.summary()
print(parent_summary.summary.current_parent_company_name, parent_summary.summary.major_industry)
except ViolationNotFound as exc:
print(f"Parent not found: {exc}")
print("exercised: violationsummaries.search / details / agencies.list / agency.summary / parent.summary")
Full-text search over corporate violation records with filters on company, agency, year, penalty amount, offense group, and industry. Returns paginated results sorted by penalty amount descending by default. Each result includes the violation ID slug for drilling into full details via get_violation_detail.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination (1-based). |
| sort | string | Sort field. |
| year | string | Year filter (comma-separated for multiple, e.g. '2020,2021,2022'). |
| order | string | Sort order. |
| pen_op | string | Penalty comparison operator. |
| company | string | Company name to search for. |
| case_type | string | Case type filter. |
| parent_op | string | Parent name match operator. |
| company_op | string | Company name match operator. |
| action_type | string | Action type filter. |
| agency_code | string | Agency code filter (e.g. 'EPA', 'OSHA', 'SEC'). |
| parent_name | string | Parent company name filter. |
| offense_type | string | Offense type filter. |
| offense_group | string | Offense group filter. |
| federal_agency | string | Federal agency filter (comma-separated for multiple). |
| major_industry | string | Major industry filter (comma-separated for multiple). |
| penalty_amount | string | Minimum penalty amount. |
| state_local_agency | string | State/local agency filter (comma-separated for multiple). |
| level_of_government | string | Level of government filter. |
| presidential_administration | string | Presidential administration filter. |
{
"type": "object",
"fields": {
"results": "array of violation record objects containing company, current_parent, year, agency, penalty_amount, primary_offense_type, violation_id, and parent_id",
"pagination": "object with current_page (integer) and has_next (boolean), or null if no pagination",
"total_results_text": "string describing the total number of matching records"
}
}About the Goodjobsfirst API
Search and Filter Violations
The search_violations endpoint is the primary query surface. It accepts filters including company (name substring), year (single or comma-separated list like 2020,2021,2022), case_type, and pen_op (a penalty comparison operator for threshold filtering). Results are paginated objects containing pagination.current_page, pagination.has_next, total_results_text, and an array of violation records. Each record in the array includes company, current_parent, year, agency, penalty_amount, primary_offense_type, and a violation_id slug used to fetch full details.
Violation Detail and Company Summaries
get_violation_detail accepts a violation_id slug (e.g. epa-exxon-mobil-corp) and returns the full record: violation_description, offense_group, primary_offense, penalty, agency, and current_parent_company. get_parent_company_summary takes a parent_id slug and returns a summary object with fields like penalty_total_since_2000_for_..., major_industry, headquartered_in, and ownership_structure, plus arrays of individual violations, top offense_types, and top offense_groups — useful for building a compliance profile of a single corporate family.
Agency-Level Enforcement Data
get_agency_summary accepts an agency_code (e.g. EPA, OSHA, SEC, DOJ_CRIMINAL, WHD) and returns the agency's penalty_total_since_2000, number_of_records, a list of top 10 parent companies by total_penalty_dollars, and recent major violations. The list_agencies and list_parents endpoints return complete reference lists — agency codes with full names, and parent company slugs with display names — which map directly to the parameters used across other endpoints.
The Goodjobsfirst API is a managed, monitored endpoint for violationtracker.goodjobsfirst.org — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when violationtracker.goodjobsfirst.org changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official violationtracker.goodjobsfirst.org API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a corporate compliance history tool showing penalty totals and offense breakdowns by parent company using
get_parent_company_summary - Track enforcement trends across federal agencies by comparing
penalty_total_since_2000andnumber_of_recordsfromget_agency_summary - Filter violations by year range and company name to research a specific firm's regulatory history before a business partnership
- Aggregate
primary_offense_typedistributions fromsearch_violationsto identify which offense categories generate the largest penalties in a given industry - Build journalist or watchdog tooling that links violation IDs from search results to full
violation_descriptiontext viaget_violation_detail - Screen parent company slugs from
list_parentsagainst your portfolio companies to surface any with significant enforcement records - Compare agency enforcement activity by querying multiple agency codes and ranking them by total penalties and record counts
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Good Jobs First provide an official developer API for Violation Tracker?+
How does pagination work in `search_violations`, and how do I know if there are more pages?+
pagination object with current_page (integer) and has_next (boolean). Pass the page parameter to advance through results. If has_next is false, you have reached the last page. The total_results_text field in the response gives a human-readable count of matching records.Does the API cover state-level regulatory agencies or only federal ones?+
Are there any known reliability issues with specific endpoints?+
get_parent_company_summary notes that some large parent companies with extensive violation histories may experience intermittent upstream timeouts. This is a function of the volume of records being aggregated for those companies, not a general API stability issue. Building in retry logic for that endpoint is advisable for the largest corporate families.Can I filter `search_violations` results by industry or offense group?+
search_violations endpoint currently supports filters for company, year, case_type, pen_op, and parent_op, but does not expose a direct industry or offense_group filter parameter. Offense group data is available in violation detail and parent summary responses. You can fork this API on Parse and revise it to add an offense_group or industry filter to the search endpoint.