Skip to content

Ingest · data

Point-in-Time API

Give it a company and a timestamp and it returns the filings that were public at that minute. Every answer repeats which timestamp field it filtered on and lists a certificate for each day it read.

  • LIVE
  • REST
  • JSON
  • SSE

Researcher $29 / Power $79 / Desk $499 monthly. The sample routes below take no key.

The artifact

One request, and what came back

SVB Financial Group filed an 8-K on 10 March 2023. This asks for what was public at the end of that day, against the hosted sample route, which needs no key.

GET /v1/sample/news · example=svb 200 · count 1

$ curl -s "https://api.pit.aqx.llc/v1/sample/news?example=svb&as_of=2023-03-10T23:59:59Z&visible_by=published_at"
{
  "request_id": "c4a244b3-60c0-4a77-8b29-b94d5bbb063a",
  "corpus_version": "sha256:sample",
  "as_of": "2023-03-10T23:59:59Z",
  "visible_by": "published_at",
  "status": "ok",
  "results": [
    {
      "id": "0001193125-23-067777_719739",
      "source_id": "sec.edgar",
      "lane": "certified_pit",
      "form": "8-K",
      "accession": "0001193125-23-067777",
      "cik": "719739",
      "title": "SVB FINANCIAL GROUP 8-K",
      "event_at": null,
      "published_at": "2023-03-10T23:59:59Z",
      "available_at": null,
      "acceptance_at": "2023-03-10T22:23:03Z",
      "committed_at": "2026-08-25T09:18:11Z",
      "availability_basis": "unknown",
      "content_sha256": "8a95862ef3953dd206f1afeb5a0ab19014b57f7f332b764e948f6514fdd2d06a",
      "source_locator": "https://www.sec.gov/Archives/edgar/data/719739/000119312523067777/0001193125-23-067777.txt",
      "sample": true,
      "as_of_visible": true
    }
  ],
  "count": 1,
  "coverage": {
    "touched": [
      "identity.ticker/SIVB@2023-03-10",
      "sec.edgar/2023-03-10",
      "sec.edgar/frontier:2020-02-18..2023-03-10;holes=0",
      "us.federal_register.pi/2023-03-10",
      "us.federal_register.pi/frontier:2020-02-18..2023-03-10;holes=0"
    ],
    "missing": []
  },
  "error": null
}

Run on 2026-08-27. request_id and corpus_version change per call; the row does not.

Move the cut back to 20:00Z on 9 March and the same call answers 200 with count: 0 and the same empty coverage.missing. The 8-K was not public yet, and we hold a certificate for that day saying we read it and found nothing.

Ask instead for the strictest clock, available_at, and the call refuses. No publisher clock records when EDGAR disseminated this filing, so available_at is null on the row, and a cut on a null clock is answered as 409 rather than as a count of zero.

visible_by=available_at 409 · coverage_missing

$ curl -s "https://api.pit.aqx.llc/v1/sample/news?example=svb&as_of=2023-03-10T23:59:59Z&visible_by=available_at"
{
  "status": "coverage_missing",
  "results": [],
  "count": null,
  "coverage": {
    "missing": ["availability.sec.edgar/2023-03-10"]
  },
  "error": {
    "code": "coverage_missing",
    "message": "This cut touches at least one day we have not certified, so count is null: the answer is unknown, not empty. coverage.missing names the days.",
    "param": null
  }
}

The failure it prevents

One filing, two clocks, twenty-two hours apart

data/raw/sec/2023-03/2023-03-10/master.idx line 4,543

CIK|Company Name|Form Type|Date Filed|File Name
719739|SVB FINANCIAL GROUP|8-K|20230310|edgar/data/719739/0001193125-23-067777.txt

The only time on that line is 20230310. EDGAR also stamps the minute it accepted a submission, and for this filing that minute was 22:23:03Z. A join on the date column hands the 8-K to your model at midnight UTC, twenty-two hours before EDGAR had it, and nothing in the date column tells you so.

10.3% of filings are accepted after the day boundary a naive join uses
1.1h median distance between the two clocks
343d the largest one

We put a number on what that gap is worth. One strategy, one basket of twelve Dow issuers, one price series, 88 8-K filings between 2022-11-01 and 2023-03-31, and the clock as the only input that changes: the naive filed-date join returns +5.13%, the same strategy waiting for the nightly EDGAR dump returns −2.02%, and the acceptance receipt returns +0.18%. On 47 of the 64 filings that carry a receipt, the naive arm's entry auction opened before EDGAR had accepted the filing, a mean of 6.05 hours before, so that first curve was never reachable by anyone.

The basket rule, the exclusions and the per-event timing are on benchmarks, and the method is written up in methods.

How it works

Five clocks on the row, three you may cut on

The clock vocabulary

Every row carries event_at, published_at, available_at, acceptance_at and committed_at. The visible_by parameter takes published_at, available_at or committed_at, and defaults to the first. A row is in the cut when its named clock is at or before as_of, compared in UTC and inclusive at both ends. Naming acceptance_at returns 400 with invalid_clock, because an acceptance receipt records when EDGAR took the file rather than when a reader could fetch it.

Null clocks

If the clock you named is null on a row, the cut leaves that row out and the day turns up in coverage.missing, so you see the hole instead of a quietly smaller answer.

A certificate per day

coverage.touched lists every source-day the answer rests on, including the frontier the corpus was read to. A day we have not certified makes the whole call 409 with count as JSON null, which is how you tell an uncertified day apart from a day we read and found empty.

Identity at the instant

Tickers are not stored on the filing row. /v1/mapping resolves a ticker to a CIK as of the query instant, which is how a 2021 query for FB reaches the company that later renamed itself. Joining on today's ticker table uses a mapping that did not exist when the query says it is standing.

Two lanes

Backfilled rows arrive on certified_pit and rows the live tape observed arrive on forward_first_seen. One answer carries one lane, so what a publisher asserted stays separable from what we watched happen.

What the corpus holds

Read from /v1/meta on 2026-08-27: 587,748 queryable rows across seven public sources, with partitions running from 2008-09-01 to that morning. sec.edgar is 564,518 of them and us.federal_register.pi is 21,931. The endpoint takes no key, so this paragraph is checkable from a browser.

Integration

Six lines of Python

The package is pitnews. It is stdlib only, so there is nothing to resolve, and it reads your key from PIT_API_KEY when you pass none.

as_of query python

from pitnews import PitClient

client = PitClient()                       # or PitClient(api_key="pit_live_…")

page = client.query_as_of(
    ticker="SIVB",
    known_at="2023-03-10T23:59:59Z",
    visible_by="published_at",
    source="sec.edgar",
)
print(page["count"], page["coverage"]["missing"])

query_as_of returns one page and count is that page's rows rather than the size of the cut. fetch_all_as_of follows the cursor for you, and iter_as_of streams. Passing source narrows what the answer depends on: without it this cut also rests on CFTC and OFAC days the corpus does not hold, and the call answers 409 naming them.

Install from the clone with pip install ./clients/python until the PyPI release. A Go client sits in clients/go, and the OpenAPI document is at /v1/openapi.json.

Related

Upstream and downstream

Live Feed
The forward half of the same record. It writes new rows every fifteen minutes and stamps each one with the minute we first saw it.
Flat Files
The same rows as parquet partitions, for work that reads the corpus rather than querying it.
Benchmark Datasets
A frozen window of these rows with matched control arms, for scoring an agent.
MCP Server
The same cuts as tools an agent can call, with known_at on every question.

Plans and rate limits are on the pricing page. A self-serve key covers work you run for yourself or your employer; if your own users end up holding PIT rows you need a commercial license.