---
title: "Get Capture Install Receipt"
method: GET
path: "/api/captures/install-receipt"
tags: ["captures"]
---

# Get Capture Install Receipt

`GET /api/captures/install-receipt`

## Request

- Base URL: `https://app.thinqos.com` (the document declares no server; this is the origin it was published from)
- URL: `https://app.thinqos.com/api/captures/install-receipt`
- Auth: none declared

Bounded, owner-scoped answer to "did this installation attempt arrive".

TOS-4487. This is what makes the historical-session false positive
impossible: the only acceptable proof of a fresh install is a receipt
matching THIS attempt id and THIS source, inside a server-clock age
window - never "any existing session for this source".

``machine_id`` is an OPTIONAL narrowing filter, not a required one, and is
returned as evidence instead. The browser cannot know it: the CLI mints it
locally per account binding and never tells the UI. The attempt id is the
correlation key the caller actually owns - 128 random bits it generated for
this one attempt - so requiring machine_id as an input would only have made
the endpoint uncallable from the surface it exists to serve.

Ownership is enforced by filtering on ``(identity_id, attempt_id)``
first, exactly like ``get_external_session``: a foreign or never-arrived
attempt_id can never match another caller's own identity_id, so this
returns 404 with no existence disclosure whether the attempt belongs to
someone else or never happened at all. A match that DOES exist for this
caller but under a different source/machine_id, or outside
``max_age_seconds``, is deliberately NOT a 404 - it is a 200 with every
fact false, because the attempt genuinely is this caller's own and simply
has not (or no longer) produced matching evidence.

Never pages through capture history: the lookup is one indexed equality
scan on ``(identity_id, attempt_id)`` - the leading columns of
``CaptureInstallReceipt``'s unique constraint, so no extra index is
needed - bounded by a small LIMIT, and every install attempt has at most
one row per distinct trigger by construction.

## Query parameters

- `attempt_id` string, required
- `source` string, required
- `machine_id` string, nullable
- `max_age_seconds` integer

## Headers

- `x-ingest-key` string, nullable
- `authorization` string, nullable
- `x-impersonate-identity-id` string, nullable

## Response `200`

Successful Response

- CaptureInstallReceiptV1: Response for ``GET /api/captures/install-receipt`` (TOS-4487). Four independent facts that must never be collapsed into one boolean: ``configuration`` (a ``thinqos_install`` marker with trigger ``configuration`` arrived), ``transport`` (one with trigger ``transport_probe`` arrived - proves the client could reach the API, not that anything was installed), ``native_hook`` (one with trigger ``native_hook`` arrived - the ONLY fact a genuine hook firing may set; a ``sweep`` or ``transport_probe`` marker never sets it), and ``learning`` (read from the matched capture's own extraction eligibility/status, and NOT implied by any of the other three - a probe or below-minimum capture can satisfy every trigger fact and still never be eligible for personal learning). ``server_observed_at`` is the server clock timestamp of the freshest matching receipt, or ``null`` when nothing currently matches. ``machine_ids`` reports which machines those receipts came from.
  - `configuration` boolean, required
  - `transport` boolean, required
  - `native_hook` boolean, required
  - `learning` boolean, required
  - `server_observed_at` string, date-time, nullable, required
  - `machine_ids` string[]

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/thinqos/apis/thinqos-api.md) · [All operations](https://skmtc.dev/thinqos/apis/thinqos-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thinqos/apis/thinqos-api/revisions/ce2c2ce318b1?raw)
