HEADLESS RECORDS DOCS

API reference

The API repo owns these contracts. The examples below are copied from canonical API artifacts, not generated by live calls from the landing page.

Protected endpoints

Protected endpoints require X-API-Key. Use hr_live_REPLACE_ME in public examples.

GET /v1/freshness

Purpose
Returns ingestion freshness over the bounded enabled watched ticker universe for the API key.
Authentication
Protected. Send X-API-Key.
Parameters
Optional query param freshness_window_hours. Default 24. Bounds 1 through 168.
Common errors
401 unauthorized, 400 invalid_freshness_window, 429 rate_limited, 500 internal_error.
Caveats
Freshness covers only configured enabled watched tickers and does not fetch SEC data live.

Example curl

curl 'https://api.headlessrecords.dev/v1/freshness?freshness_window_hours=24' \
  -H 'X-API-Key: hr_live_REPLACE_ME'

Canonical example response

{
  "request_id": "req_example_freshness",
  "api_version": "v1",
  "generated_at": "2026-05-21T12:00:00Z",
  "data_as_of": "2026-05-21T11:55:00Z",
  "freshness_window_hours": 24,
  "status": "degraded",
  "summary": {
    "enabled_tickers": 3,
    "fresh": 1,
    "stale": 0,
    "degraded": 1,
    "failed": 0,
    "sync_running": 1,
    "never_synced": 0
  },
  "tickers": [
    {
      "ticker": "AAPL",
      "freshness_status": "fresh",
      "last_attempted_sync_at": "2026-05-21T11:50:00Z",
      "last_completed_sync_at": "2026-05-21T11:55:00Z",
      "last_successful_sync_at": "2026-05-21T11:55:00Z",
      "last_status": "completed",
      "last_discovered_count": 2,
      "last_imported_count": 2,
      "last_skipped_count": 0,
      "last_failed_count": 0,
      "last_error_message": null
    },
    {
      "ticker": "TSLA",
      "freshness_status": "degraded",
      "last_attempted_sync_at": "2026-05-21T11:40:00Z",
      "last_completed_sync_at": "2026-05-21T11:45:00Z",
      "last_successful_sync_at": "2026-05-20T11:45:00Z",
      "last_status": "completed_with_errors",
      "last_discovered_count": 3,
      "last_imported_count": 2,
      "last_skipped_count": 0,
      "last_failed_count": 1,
      "last_error_message": "One filing could not be imported."
    },
    {
      "ticker": "NVDA",
      "freshness_status": "sync_running",
      "last_attempted_sync_at": "2026-05-21T11:58:00Z",
      "last_completed_sync_at": null,
      "last_successful_sync_at": "2026-05-20T11:55:00Z",
      "last_status": "running",
      "last_discovered_count": 0,
      "last_imported_count": 0,
      "last_skipped_count": 0,
      "last_failed_count": 0,
      "last_error_message": null
    }
  ],
  "methodology": [
    "Freshness is computed from ingestion status rows for enabled watched tickers.",
    "A ticker is fresh when the latest completed sync is inside freshness_window_hours."
  ],
  "caveats": [
    "Freshness covers the configured bounded watched ticker universe only.",
    "This response reflects imported public SEC filing data only and does not fetch live SEC data."
  ]
}

GET /v1/insider-activity/{ticker}/assessment

Purpose
Returns a deterministic, non-advisory assessment of reported SEC Form 4 insider activity for one ticker.
Authentication
Protected. Send X-API-Key.
Parameters
Path param ticker. Optional query params period, default 90d, values 30d, 90d, 180d; freshness_window_hours, default 24, bounds 1 through 168.
Common errors
401 unauthorized, 400 invalid_ticker, 400 invalid_period, 400 invalid_freshness_window, 429 rate_limited, 500 internal_error.
Caveats
Unknown tickers or tickers with no imported transactions may return 200 with no activity, empty sources, and caveats. The assessment summarizes public filing activity only.

Example curl

curl 'https://api.headlessrecords.dev/v1/insider-activity/TSLA/assessment?period=90d&freshness_window_hours=24' \
  -H 'X-API-Key: hr_live_REPLACE_ME'

Canonical example response

{
  "request_id": "req_example_assessment",
  "api_version": "v1",
  "generated_at": "2026-05-21T12:00:00Z",
  "data_as_of": "2026-05-20T00:00:00Z",
  "ticker": "TSLA",
  "period": "90d",
  "freshness": {
    "freshness_window_hours": 24,
    "status": "degraded",
    "last_attempted_sync_at": "2026-05-21T11:40:00Z",
    "last_completed_sync_at": "2026-05-21T11:45:00Z",
    "last_successful_sync_at": "2026-05-20T11:45:00Z",
    "last_status": "completed_with_errors"
  },
  "assessment": {
    "activity_level": "moderate",
    "dominant_activity": "sales",
    "data_quality": "degraded",
    "summary_text": "Reported insider activity was moderate during the selected period, with sales as the dominant reported activity. Data quality is degraded."
  },
  "summary": {
    "transaction_count": 3,
    "sale_transaction_count": 3,
    "purchase_transaction_count": 0,
    "other_transaction_count": 0,
    "missing_price_count": 0,
    "missing_share_count": 0,
    "filing_count": 1,
    "filings_with_source_provenance_count": 1
  },
  "caveats": [
    {
      "code": "freshness_degraded",
      "severity": "warning",
      "message": "The latest SEC Form 4 sync completed with errors, so freshness is degraded."
    },
    {
      "code": "form4_amendments_excluded",
      "severity": "warning",
      "message": "Form 4/A amendments are currently excluded until amendment semantics are implemented."
    },
    {
      "code": "period_limited",
      "severity": "info",
      "message": "This assessment covers only the selected period."
    },
    {
      "code": "scheduled_plan_context_not_extracted",
      "severity": "info",
      "message": "This assessment does not currently extract or classify 10b5-1 or other scheduled-plan context."
    },
    {
      "code": "limited_insider_role_context",
      "severity": "info",
      "message": "Insider role context is limited to relationship fields present in imported filings."
    },
    {
      "code": "limited_watchlist_coverage",
      "severity": "info",
      "message": "Coverage is bounded to the configured enabled watchlist and imported public filing data."
    },
    {
      "code": "insider_activity_not_necessarily_predictive",
      "severity": "info",
      "message": "Reported insider activity is not necessarily predictive because transactions may have scheduled, tax, compensation, diversification, or other context."
    },
    {
      "code": "not_financial_advice",
      "severity": "info",
      "message": "This response summarizes public filing data and is not financial advice."
    }
  ],
  "methodology": {
    "version": "2026-05-11",
    "name": "insider_activity_assessment_v1",
    "description": "Summarizes reported insider filing activity using deterministic, non-advisory rules.",
    "rules": [
      "Counts imported SEC Form 4 transactions during the selected period.",
      "Classifies reported acquisition and disposition codes into descriptive activity counts.",
      "Reports freshness, caveats, methodology, and source provenance so agents can preserve context."
    ]
  },
  "sources": [
    {
      "accession_number": "0000001318-26-000123",
      "filing_date": "2026-05-20",
      "provenance_status": "available",
      "source_document_url": "https://www.sec.gov/Archives/edgar/data/1318605/000000131826000123/primary_doc.xml",
      "source_metadata_url": "https://data.sec.gov/submissions/CIK0001318605.json",
      "retrieved_at": "2026-05-20T18:00:00Z",
      "content_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    }
  ]
}

GET /v1/provenance/filing/{accession_number}

Purpose
Returns source provenance for a successfully imported filing linked to a source document.
Authentication
Protected. Send X-API-Key.
Parameters
Path param accession_number in SEC accession format 0000000000-00-000000.
Common errors
401 unauthorized, 400 invalid_accession_number, 404 not_found, 404 provenance_not_available, 429 rate_limited, 500 internal_error.
Caveats
Hashes identify source document bytes processed by Headless Records. They do not mean the SEC signed the data.

Example curl

curl 'https://api.headlessrecords.dev/v1/provenance/filing/0000001318-26-000123' \
  -H 'X-API-Key: hr_live_REPLACE_ME'

Canonical example response

{
  "request_id": "req_example_provenance",
  "api_version": "v1",
  "generated_at": "2026-05-21T12:00:00Z",
  "accession_number": "0000001318-26-000123",
  "provenance_status": "available",
  "source": {
    "source": "sec_form4",
    "source_document_url": "https://www.sec.gov/Archives/edgar/data/1318605/000000131826000123/primary_doc.xml",
    "source_metadata_url": "https://data.sec.gov/submissions/CIK0001318605.json",
    "retrieved_at": "2026-05-20T18:00:00Z",
    "content_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "content_size_bytes": 12345,
    "content_type": "application/xml",
    "parser_version": "sec-parser/0.1.0",
    "normalizer_version": "headlessrecords-ingest/0.1.0"
  },
  "methodology": [
    "The SHA-256 hash is computed over the source document bytes processed by ingestion.",
    "This proves which bytes this system processed."
  ],
  "caveats": [
    "The hash represents processed source document bytes and does not mean the SEC signed the data.",
    "This response does not make claims about investment merit or trading signals."
  ]
}

Public endpoints

GET /ready

Readiness check for serving traffic. It checks database connectivity and reports cache backend readiness.

Public.

{
  "request_id": "req_...",
  "status": "ok",
  "checks": {
    "database": { "status": "ok" },
    "cache": { "status": "ok", "backend": "memory" }
  }
}

GET /openapi.json

Serves the canonical OpenAPI contract from the API repo artifact.

Public.

OpenAPI JSON. The landing page publishes the copied copy at /api/openapi/headlessrecords.v1.json.

Error responses

Errors use a stable JSON envelope with error.code, error.message, and request_id. Rate-limited responses include a Retry-After header when available.

401 missing, invalid, or revoked API key

{
  "error": {
    "code": "unauthorized",
    "message": "A valid API key is required."
  },
  "request_id": "req_example_401"
}

404 not found

{
  "error": {
    "code": "not_found",
    "message": "Resource not found."
  },
  "request_id": "req_example_404"
}

429 rate limited

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Please retry later."
  },
  "request_id": "req_example_429"
}

500 internal error

{
  "error": {
    "code": "internal_error",
    "message": "Internal server error."
  },
  "request_id": "req_example_500"
}

Rate limits

  • GET /v1/freshness: 60 requests per minute per API key.
  • GET /v1/provenance/filing/{accession_number}: 60 requests per minute per API key.
  • GET /v1/insider-activity/{ticker}/assessment: 30 requests per minute per API key.
  • Rate limiting is in-memory in the current API process; shared limiting is required before multiple API replicas.