# Point-in-time RDAP

**Standard RDAP answers who owns this right now. This is the keyless flow for who we observed as the operator of record at a specific time, T, with a proof that folds to the same signed checkpoint as everything else in the log.**

## What point-in-time RDAP is

[RDAP](/docs/rdap) is current-state only: query an IP, a domain, or an autonomous system number and you get today's answer. There is no standard way to ask "who was it in May." Whisper's [transparency log](/docs/transparency) already keeps a tamper-evident, append-only record of everything it issues, so instead of standing up a second history store, Whisper records what an RDAP query showed, and when, as one more leaf in that same tree, then serves it back through a small "as of T" extension of the ordinary RDAP object model.

The result composes with the other proofs on this site: the object you get back is standard [RFC 9083](/docs/rdap) JSON, and it carries a [SCITT receipt](/docs/scitt-receipts) you fold offline to the exact same root as `/checkpoint`. One log, three surfaces (identity, SCITT receipts, and this one), never a second source of truth.

## The honest data model: an observation, not a registry edit

Each time Whisper looks at a subject, it records what it saw, not what changed: *we observed `<subject>` to have operator-of-record `X`, ASN `Y`, status `Z`, at time `T`.* That observation becomes one more leaf kind in the [same tree](/docs/transparency) that already holds identity issuance and revocation events: same salted-commitment leaf rule, same single append-only log, same signed checkpoint chain, same key. Nothing about the tree changes shape to hold it; it just grows.

That framing matters for what you can trust. The leaf commits to *what we observed*, unaltered since. It does not, and cannot, commit to the registry's own ground truth, because RDAP itself carries no registry signature to anchor to (more on that below).

## The keyless flow

No API key. Ask for a subject and, optionally, a time:

| Endpoint | Returns |
|---|---|
| `GET /history/ip/<addr>[?at=<T>]` | observed operator/ASN/status history for an IP or `/128` |
| `GET /history/domain/<name>[?at=<T>]` | observed history for a domain |
| `GET /history/autnum/<asn>[?at=<T>]` | observed history for an AS number |
| `GET /operator-of-record/<subject>[?at=<T>]` | friendly alias for any of the three |

`Accept: application/rdap+json`. Omit `?at=` and you get the full observed history, oldest first; supply it and the answer collapses to the single observation current at that instant, the latest one whose `applicableFrom` is at or before `T`.

```bash
curl -s -H 'Accept: application/rdap+json' \
  'https://whisper.online/history/ip/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4?at=2026-07-01T00:00:00Z'
```

```json
{
  "rdapConformance": ["rdap_level_0", "history_0", "whisper_ledger_0"],
  "objectClassName": "history",
  "records": [
    {
      "applicableFrom": "2026-05-11T14:02:03Z",
      "content": {
        "objectClassName": "ip network",
        "handle": "2A04:2A01:EB5A:CA74:CEF2:2A:323D:40D4/128",
        "status": ["active"],
        "entities": [
          { "objectClassName": "entity", "roles": ["registrant"], "handle": "t9f3a1c2e7b4…" }
        ]
      },
      "whisperReceipt": "0oRDoQEmoQrAQ7hg9…",
      "provenance": "first-party"
    }
  ]
}
```

`content` is an ordinary [RFC 9083](/docs/rdap) object, exactly what a current-state RDAP query would have returned at that moment. `whisperReceipt` is the [SCITT receipt](/docs/scitt-receipts) for that observation's leaf, base64-encoded COSE: fold its inclusion proof offline and it byte-equals the served `/checkpoint` root at that tree size, the same fold as every other proof on this log. `provenance` says whether Whisper itself operates the subject (`first-party`) or the observation came from watching someone else's RDAP answer (`observed-external`).

A domain query follows the same shape, keyed by name instead of address:

```bash
curl -s -H 'Accept: application/rdap+json' \
  'https://whisper.online/operator-of-record/yourdomain.example?at=2026-07-01T00:00:00Z'
```

## `?at=` is our extension, not a standard

RDAP has no "as of" query parameter in RFC 9082. `?at=` (RFC 3339, epoch milliseconds, or a relative offset like `-7d`, all accepted; `?time=` also works, matching [the existing per-`/128` ownership history](/docs/rdap#ownership-history)) is Whisper's own extension, declared honestly via the `whisper_ledger_0` entry in `rdapConformance` so a generic client can tell it apart from IETF-standard behavior. Nothing here claims IETF blessing for the parameter itself; the object shape it returns follows the (expired, individual) `draft-ellacott-historical-rdap` sketch of a `history` object class, because reusing a real proposal beats inventing a fourth format.

## The boundary: what this attests

> Whisper attests that we observed this RDAP answer for the subject at that time, and that it has been unaltered since: a time-anchored, tamper-evident record of what we saw, provable against the signed checkpoint. It is not a statement that the registry's data was correct, and it does not carry the registry's own signature, because RDAP has none ([RFC 7481 §3.6](https://www.rfc-editor.org/rfc/rfc7481#section-3.6), "Data Integrity"). For subjects Whisper itself operates (`2a04:2a01::/32`, AS219419) the observation is also first-party authoritative: we are the registry, so what we observed and the registry's own truth are the same fact.

## Coverage, honestly

Three cases where a lesser system would guess; this one says so instead:

- **No RDAP source for the subject.** Not every corner of the namespace runs RDAP yet, and RFC 9224's IANA bootstrap registry is the source of truth for who does. A subject with no discoverable RDAP source gets a `notices` entry saying so, never a fabricated operator.
- **`T` before the first observation.** A plain, honest 404: no observation of that subject at or before that time, not an empty-looking 200.
- **A status Whisper hasn't indexed.** Treated as "not revoked," never invented outright.

## What's live today

The endpoints, the `history_0` shape, and the receipt above are the shipped surface. Minting new observations is rolling out gradually: coverage starts with the subjects Whisper itself operates, `2a04:2a01::/32` and AS219419, where every observation is first-party from day one. Broader external-subject coverage grows as more observations get minted; query a subject that has none yet and you get the honest empty/404 above, never a made-up answer.

## Next

[Transparency log](/docs/transparency) for the tree this rides on, [SCITT receipts](/docs/scitt-receipts) for the receipt format folded above, or [RDAP](/docs/rdap) for the current-state object model this extends.
