---
title: "One company's canonical profile and witness facts"
method: GET
path: "/api/network/profile"
---

# One company's canonical profile and witness facts

`GET /api/network/profile`

## Request

- Base URL: `https://trooth.co`
- URL: `https://trooth.co/api/network/profile`
- Auth: none required

The canonical published profile for a company, keyed by domain or slug, with the witness facts a buyer's tool needs: the `standing` field (the witnessed state), lastWitnessed (freshness), firstWitnessedAt and the unbroken run of Trooth's own hourly readings (continuity), and checksPassed out of checksRun on the signed result (coverage: checks that read as expected, out of checks run). Continuity is never claimed older than Trooth's own record and stays null until two consecutive readings agree. Responds { found: false } with 200 when no profile is published, 400 when q is missing. Cached at the edge for 120 seconds. Every response carries a `methodology` object stating the reading cadence, the gap tolerance that defines an unbroken series, the retention period, the per-category freshness windows, and an explicit list of coverage limits - what Trooth does not read. A caller restating `witnessed` or `updatedAt` elsewhere must carry those limits with it: neither field is a certification nor an audit opinion. Only the witness statement is signed; the profile, its facts and the company's text are not (see `signing`). `sectionCapabilities` links the section map, which says which sections this record and the other projections carry. Limited to 600 requests a minute and 20,000 an hour per client network (an IPv4 address, or an IPv6 /64), counted across server instances; over either window the answer is 429 with Retry-After set to the seconds until that window resets. If the counting store fails, each instance counts alone at the same ceilings and the read is not refused. Readable cross-origin: the response carries Access-Control-Allow-Origin: * and never Access-Control-Allow-Credentials, so a browser on any site may read it without cookies.

## Query parameters

- `q` string, required
- `contract` string
- `sections` string
- `limit` string
- `after` string

## Response `200`

The record, or { found: false } when the Network holds none. Which body is served is keyed by the Trooth-Contract response header: 2 (the default) is NetworkProfileV2, written to the published JSON Schema https://trooth.co/schemas/network-profile.v2.schema.json and validated against it on every push and after every deployment; 1 is NetworkProfileV1, deprecated, served only to a caller that pinned contract 1, with Deprecation and Sunset headers, until its withdrawal on 2027-03-01.

- union: NetworkProfileV2 when Trooth-Contract is 2, NetworkProfileV1 when it is 1. The two never both match: contract 1 carries contractVersion 1 and no conflicts.
  - NetworkProfileV2 (unresolved $ref)
  - NetworkProfileV1: DEPRECATED. Contract 1 of the profile read, served only to a caller that pins it with ?contract=1 or the Trooth-Contract: 1 request header, together with Deprecation and Sunset response headers, until its withdrawal on 2027-03-01 (https://trooth.co/changelog). It promises one answer per question, which holds only where no two sources disagree, so it leaves out every contested fact and names each in withheldContested. A query the Network holds no profile for answers the contract 2 notFound body ({ found: false }) under either contract. Derived from lib/network/public-profile-v1.ts by scripts/gen-openapi.mjs.
    - `contractVersion` unknown, required
    - `contractNote` string, required: What the contract version promises, as a sentence.
    - `contractOmissions` string[], required: Fields this contract deliberately does not carry, each with the reason, so a reader does not look for them.
    - `deprecation` string, required: The withdrawal notice. Contract 1 is withdrawn on 2027-03-01; the same date is in the Sunset response header.
    - `requestedContract` integer, nullable: The contract the caller asked for with ?contract= or the Trooth-Contract header, or null when it asked for none. contractVersion is the contract that served the response. Additive in contract 2 (2026-09-26).
    - `contractSchema` unknown
    - `witnessStatement` NetworkProfileV2WitnessStatement: Trooth's signed statement of the reading behind `witnessed`, carried exactly as the upstream witness worker signed it. Present only when that reading was signed under the witness statement; absent (the key is not in the body) for an older reading, which is not a failed check. `payload` is the signing input itself: check the Ed25519 signature over its UTF-8 bytes with the key `key_id` names at https://api.trooth.co/public/keys, decoding that key by its `encoding`, then parse `payload` to read it. Two versions exist, named by the payload's own `statement` field. trooth.witness-statement.v2 (readings signed from 2026-10-04) carries `statement`, `reading_id`, `domain`, `read_at`, `subject_scope` (`domain`, `surface`, `checks_in_scope`), `methodology` (`standard`, `mapping_version`, `mapping_url`, `mapping_digest`: sha256 over the exact bytes of the immutable mapping file at https://trooth.co/standard/check-mapping/<version>.json), `evaluator` (`name`, `version`), `evidence_manifest` (`digest`, `entries`, `canonicalization`), `checks` (each with `id`, `category`, `kind`, an `outcome` of `as expected`, `not as expected` or `not read`, and for every outcome other than `as expected` a `reason` with a versioned `code`, a `source_ref` or an explicit `withheld` and `withheld_reason`) and `counts` (`read`, `as_expected`, `not_as_expected`, `not_read`, `in_reading`, with read + not_read = in_reading and as_expected + not_as_expected = read). A timeout or an unavailable source is `not read`, never `not as expected`. trooth.witness-statement.v1 (earlier readings) carries `statement`, `reading_id`, `domain`, `read_at`, `checks` (`id`, `category`, `kind`, `outcome`) and `counts` (`read`, `as_expected`). Its assurance is narrower: it shows the key signed those outcome bytes and does not bind the check mapping, the evaluator version, the subject scope or the evidence sources. No digest is ever added to a v1 statement. Neither version carries a verdict, a threshold or a composite figure. This is the only signed part of the body. Trooth signs what it witnessed. It never signs on a company's behalf.
      - `payload` string, required: The exact string that was signed. Do not re-serialize it before checking.
      - `signature` string, required: The prefix `ed25519:` followed by the standard base64 of the 64 signature bytes.
      - `key_id` string, required: The `kid` of the signing key at https://api.trooth.co/public/keys.
      - `alg` 'Ed25519', required: The signature algorithm: Ed25519 (RFC 8032).
      - `canonicalization` string, required: How the worker serialized the payload before signing: JSON with keys in a fixed order and no whitespace, as UTF-8. `payload` is already in that form.
    - `witnessEvidenceManifest` union[]: The evidence manifest a trooth.witness-statement.v2 statement binds through `evidence_manifest.digest`: one entry per check, each a public `source` reference or a `commitment` (sha256 over a secret salt, one 0x0a byte and a private reference) where publishing the reference would expose a company's declaration or a sensitive path. Recompute the digest as sha256 over the UTF-8 bytes of the entries sorted by `check_id` and serialized as JSON with keys `check_id` then `source` or `commitment` and no whitespace, and compare it to the signed digest. Additive (2026-10-04); present only beside a v2 statement, never beside v1, and not itself signed.
      - union
        - object
          - `check_id` string, required: The check id in the mapping the statement names. Unique in the manifest.
          - `source` string, required: The public URL the check read.
        - object
          - `check_id` string, required: The check id in the mapping the statement names. Unique in the manifest.
          - `commitment` string, required: sha256 over a secret salt, one 0x0a byte and the private reference; only the company holding it can open it.
    - `signing` NetworkProfileV2Signing: What in this response is signed. Additive in contract 2 (2026-09-26). profileSigned is always false: the one signed object is witnessStatement, which covers one reading and nothing else.
      - `profileSigned` unknown, required
      - `signedArtifact` 'witnessStatement', nullable, required: The name of the one signed field, witnessStatement, or null when there is no statement.
      - `artifactType` 'trooth.witness-statement.v1' | 'trooth.witness-statement.v2': The signed statement's own type tag. With no statement, trooth.witness-statement.v1.
      - `subject` string, required: What the signed statement covers and does not cover, as a sentence.
      - `binding` object, nullable: What the statement binds (additive, 2026-10-04). null when there is no statement. `status` is `present` for v2 and `absent` for v1, whose assurance is narrower: v1 binds no mapping, evaluator version, scope or sources, and its digests here are null rather than filled in. This block is read from the payload; it is not a check of the signature or of the binding.
        - `status` 'present' | 'absent', required: present for a v2 statement, which binds the items below; absent for v1.
        - `mappingVersion` string, nullable
        - `mappingUrl` string, nullable
        - `mappingDigest` string, nullable
        - `evaluatorVersion` string, nullable
        - `evidenceManifestDigest` string, nullable
        - `assurance` string, required: What the binding shows and does not show, as a sentence.
        - `mappingVersions` string: The index of every published mapping version.
      - `keyId` string, nullable: The kid of the signing key, or null when there is no statement.
      - `keyPurpose` string: What the signing key signs, as a sentence.
      - `observedAt` string, nullable: The time the statement carries, or null. An ISO 8601 date-time in UTC, or null when none is recorded.
      - `timeSource` string: Where that time comes from. Trooth asserts it when signing; there is no external timestamp.
      - `verify` string: How to check the statement yourself.
      - `keys` string: The published key list.
      - `keyPolicy` string: The key lifecycle policy page.
    - `assuranceBoundary` object: Added 2026-10-12 (audit F-04). What this record does and does not establish. The statement is the same sentence the profile page, badge, exports and MCP answers carry.
      - `statement` 'This record organizes source-linked information for a security review. It is not an audit, certification, or suitability decision.', required: The boundary in one sentence, word for word the sentence every Trooth surface carries.
      - `doesNotEstablish` string[], required: What a Trooth record does not establish, one item each.
      - `methodology` string, required: Where the method is described: https://trooth.co/methodology.
    - `found` unknown, required
    - `slug` string, required: The company's slug on the Network; send it as q to read the same record.
    - `name` string, required: The company name as published.
    - `domain` string, nullable, required
    - `canonicalUrl` string, required: The company's public Trust Profile page, the human-readable form of this record.
    - `tagline` string, nullable, required
    - `industries` string[], required: Industries the company lists for itself.
    - `updatedAt` string, nullable, required
    - `witnessed` union, required: What Trooth itself has observed about the company's public surface. `standing` is either the word `witnessed` or null; there is no third value and no degree. Null throughout means no observation was returned, which is not a finding about the company.
      - object
        - `standing` 'witnessed', required: The word witnessed: Trooth has a reading of this public surface. It is not a grade and has no degrees.
        - `lastWitnessed` string, nullable, required
        - `firstWitnessedAt` string, nullable, required
        - `coverage` object, nullable, required: What the latest reading counted, reported apart and never combined into one number; null when no counts are available.
          - `checksPassed` integer, required: Checks read whose outcome was as expected. Part of checksRun, not a separate addend.
          - `checksRun` integer, required: Checks read in the latest reading.
          - `source` 'witness_statement' | 'result_tally': What checksRun and checksPassed count. witness_statement: computed from the signed witness statement's entries; checksRun is checks read in this reading. result_tally: the reading's own tally for a reading with no statement; not a count of checks read. Additive in contract 2 (2026-09-26); absent on responses served before it.
          - `definition` string: The same meaning, as a sentence.
          - `checksNotRead` integer: Entries in the reading that were not read in it. Present when source is witness_statement.
          - `checksNotAsExpected` integer: Entries read whose outcome was not as expected: checksRun minus checksPassed, so checksRun = checksPassed + checksNotAsExpected. Present when source is witness_statement. Additive (2026-09-28).
          - `checksInReading` integer: checksRun plus checksNotRead. Present when source is witness_statement.
        - `continuity` object, required: How long readings have run without a gap longer than methodology.gapTolerance.
          - `recordBegan` string, nullable, required
          - `unbrokenSince` string, nullable, required
          - `unbrokenReadings` integer, required: Readings in the current unbroken series.
          - `totalReadings` integer, required: Readings kept in the retention window.
      - object
        - `standing` unknown, required
        - `lastWitnessed` unknown, required
        - `firstWitnessedAt` unknown, required
        - `coverage` unknown, required
        - `continuity` unknown, required
    - `methodology` NetworkProfileV2Methodology, required: How the witnessed block was produced and what it does not cover. Included in every response so a reader restating witnessed elsewhere can carry the limits with it.
      - `cadence` string, required: How often readings are attempted, as a sentence.
      - `gapTolerance` string, required: The longest gap between readings that still counts as unbroken, as a sentence.
      - `retention` string, required: How long readings are kept, as a sentence.
      - `freshness` object[], required: For each category of fact, how long an observation stays current.
        - `category` string, required: The fact category id.
        - `label` string, required: The category as words.
        - `window` string, required: How long an observation in this category stays current, as words (for example 48 hours).
      - `exclusions` string[], required: What the readings do not cover, one sentence each.
      - `summary` string, required: The methodology in one paragraph, for a reader restating witnessed elsewhere.
    - `facts` NetworkProfileV1Fact[], required: Every fact no two sources answered differently. A contested fact is left out, never resolved to one account, and its key is named in withheldContested.
      - `key` string, required: The stable field key, section.field (for example identity.legal-name).
      - `category` string, required: The section the fact belongs to, as words.
      - `label` string, required: The field name, as words.
      - `value` string, required: The value as published, as text.
      - `origin` 'company-declared' | 'witnessed' | 'public-source', required: Who said it. company-declared is the company's own statement; witnessed is Trooth's observation; public-source is a named third party. The order accounts are listed in is fixed and is not a ranking.
      - `fact_id` string: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). The stable fact id, <section>.<field>: the section name the .md, JSON and MCP surfaces share and the field's key in lower snake case; a list member adds .member.<member key>. Never contains the record version.
      - `anchor_url` string: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). The fact's anchor on the canonical page: #fact-<fact_id with . written as ->.
      - `sentence` string: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). One self-contained sentence: subject, provenance, date and value.
      - `provenance` 'witnessed' | 'public_record' | 'attested' | 'declared': Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). witnessed: Trooth observed it (only the witness statement is signed). public_record: read from a public registry. attested: a named counterparty stated it. declared: the company stated it.
      - `freshness_window` string, nullable: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). The methodology's freshness window for this fact as an ISO 8601 duration (P30D), or null when no window applies (a company statement Trooth does not re-read).
      - `stale_after` string, nullable: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). When the fact's dated observation goes stale, ISO 8601 with time zone, or null.
      - `witnessed_value` NetworkProfileV2WitnessedValue, nullable: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). Trooth's own observation of the same claim, from a reading the record already holds (the signed witness statement's checks, or the public record reading's security.txt), printed beside the company's declaration and never in place of it. Null when no reading observed it.
        - `value` string, required: What the reading recorded, in its own terms (check title and outcome, or the security.txt contacts read).
        - `observed_at` string, required: When the reading was taken, ISO 8601 with time zone.
        - `check` string, required: The check id or ids (for example S2), or public_record.security_txt.
      - `edit_history` NetworkProfileV2EditRecord[]: Added 2026-10-16 (record contract, https://trooth.co/methodology#record-reading). Declared facts only: the changes to this fact across the newest stored record versions (at most 25 versions), oldest first. Empty when none is held.
        - `fact_id` string, required: The fact id.
        - `old_value` string, nullable, required: The value before, or null when the fact was first published in this version.
        - `new_value` string, required: The value after.
        - `changed_at` string, required: The declaration time the newer version recorded for this value, else the time the version was recorded. ISO 8601 with time zone.
        - `actor_role` string, nullable, required: The declaring role the newer version recorded (owner, admin, editor), never a name or an email; null when none was recorded.
        - `record_version` integer, required: The stored record version that carries the new value.
    - `withheldContested` string[], required: The key of every fact left out of facts because two sources answered it differently. Read it with contract 2, which carries both accounts in conflicts.

## Other responses

- `400`: The q parameter is missing, a contract version this deployment does not answer was requested, the query and the Trooth-Contract header asked for different contracts, a section name or limit could not be applied exactly, or an after cursor is malformed, stale or was issued for other sections.
- `429`: Over the per-network budget. Retry-After is the number of seconds until the window that refused resets.
- `503`: Trooth could not read its own record on this load. Retry after the Retry-After interval; nothing is asserted about the company.

---

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