Effectivity-at-date

Vietnamese legal documents change over time along two independent axes: when CrawlPipe recorded a change (revision, system time) and when a provision was actually legally valid (legal_effectivity, valid time). The at= parameter lets you ask "what did the law say on this specific date" — including dates in the past or future relative to today, and independent of when CrawlPipe ingested the change. This is a Pro plan feature.

Document view at a date

GET /v1/legal/documents/{id}?include=units&at=2026-08-01 annotates the document and each unit with its status on that date:

curl "https://api.crawlpipe.com/v1/legal/documents/vn:tt:2026:18:btc?include=units&at=2026-08-01" \
-H "Authorization: Bearer dp_live_a1b2c3d4e5f6…"

The response adds a top-level status_at and, per unit, a status_at field:

{
  "document": {
    "units": [
      {
        "path": "c1.d1",
        "content": "Thông tư này quy định…",
        "status_at": "effective"
      }
    ],
    "status_at": { "date": "2026-08-01", "status": "effective" }
  }
}

natural_key (e.g. vn:tt:2026:18:btc), the record's UUID, or its normalized doc_number all work as {id}.

Full timeline

GET /v1/legal/documents/{id}/effectivity (1 unit; the at param on this endpoint also requires Pro) returns the whole history as a sequence of validity windows, including future-dated amendments that haven't taken effect yet:

{
  "effectivity": [
    { "unit_path": null, "status": "not_yet_effective", "valid_from": "2026-05-12", "valid_to": "2026-06-30", "caused_by": null },
    { "unit_path": null, "status": "effective", "valid_from": "2026-07-01", "valid_to": null, "caused_by": null },
    {
      "unit_path": "d3.k2",
      "status": "amended",
      "valid_from": "2026-09-01",
      "valid_to": null,
      "caused_by": { "record_id": "…", "doc_number": "45/2026/TT-BTC", "relation_type": "sua_doi_bo_sung" }
    }
  ]
}

A null unit_path describes the whole document; specific paths describe amendments scoped to one khoản/điều. caused_by points at the amending document so you can follow the chain.

Why this matters

A naive integration that always reads "current" text will silently serve outdated or not-yet-effective language around an amendment's effective date. Use at= to pin the exact date relevant to your use case — e.g. the invoice date in an accounting sync, or "today" evaluated in Vietnam time — instead of whatever happens to be current when you call the API.

Plan gating

at= on both endpoints returns 403 feature_not_in_plan (details.required_plan: "pro") on Free and Builder. Without at=, both endpoints work on every plan and simply return current-state data.

Effectivity-at-date — CrawlPipe Docs