> ## Documentation Index
> Fetch the complete documentation index at: https://docs.factagora.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DeepStamp

> Embed a structure-based watermark into content and detect reuse of it.

DeepStamp proves that a piece of content originated from you, even after it has been rewritten or translated. Embedding extracts a Temporal Knowledge Graph (TKG) from your content and hides a watermark seeded by that structure. Detection scores candidate content against every stored fingerprint using both the watermark and the causal structure.

<Note>
  **DeepStamp is the product name; the API paths still say `fingerprint`.** Endpoints are `/api/v1/fingerprint/embed` and `/api/v1/fingerprint/detect`, and responses return `fingerprint_id`. There is no `/api/v1/deepstamp/*` endpoint.
</Note>

## Endpoints

| Method | Path                         | Purpose                                                   |
| ------ | ---------------------------- | --------------------------------------------------------- |
| `POST` | `/api/v1/fingerprint/embed`  | Extract a TKG, embed the watermark, store the fingerprint |
| `POST` | `/api/v1/fingerprint/detect` | Score content against stored fingerprints                 |

***

## POST /api/v1/fingerprint/embed

### Request Body

Provide either `content` or `url`, not both.

<ParamField body="content" type="string">
  Raw text to fingerprint. Maximum 50,000 characters.
</ParamField>

<ParamField body="url" type="string">
  URL of the source document to fingerprint.
</ParamField>

<ParamField body="content_type" type="string" default="news">
  Category of the content. One of `news`, `report`, `legal`, `internal`. This also selects the default scoring weights used at detection time.
</ParamField>

<ParamField body="metadata" type="object">
  Your own identifiers, stored with the fingerprint and echoed back on every match.

  <Expandable title="Metadata fields">
    <ParamField body="author_id" type="string">Internal author identifier</ParamField>
    <ParamField body="published_at" type="string">ISO 8601 publish timestamp</ParamField>
    <ParamField body="source_id" type="string">Upstream source identifier, such as a CMS article id</ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/fingerprint/embed" \
    -H "Authorization: Bearer fa_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "content": "The European Central Bank raised interest rates by 25 basis points on Thursday, citing persistent core inflation in the eurozone.",
      "content_type": "news",
      "metadata": {
        "author_id": "editor_jane",
        "published_at": "2024-06-15T08:00:00Z",
        "source_id": "article_12345"
      }
    }'
  ```
</RequestExample>

### Response

<ResponseField name="watermarked_content" type="string">
  Your content with the TKG-seeded zero-width watermark embedded. Distribute this version, not the original.
</ResponseField>

<ResponseField name="fingerprint_id" type="string">
  Unique fingerprint identifier (`fp_*`). Store it alongside your internal article id.
</ResponseField>

<ResponseField name="tkg_snapshot" type="object">
  The structure extracted from your content.

  <Expandable title="Snapshot fields">
    <ResponseField name="entities" type="array">Distinct entities found in the content</ResponseField>
    <ResponseField name="timeseries" type="array">Normalized time anchors (`YYYY`, `YYYY-MM`, or `YYYY-MM-DD`)</ResponseField>
    <ResponseField name="relations" type="array">Causal or temporal relations as `from` / `rel` / `to` triples</ResponseField>
    <ResponseField name="argument_map" type="array">Premise → evidence → conclusion chains</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="embed_timestamp" type="string">
  ISO 8601 timestamp of when the fingerprint was embedded.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "watermarked_content": "The European Central Bank raised interest rates by 25 basis points...",
    "fingerprint_id": "fp_l1p8OPCwGhvu",
    "tkg_snapshot": {
      "entities": ["European Central Bank", "Interest rate", "Goldman Sachs"],
      "timeseries": ["2024-06-15"],
      "relations": [
        { "from": "European Central Bank", "rel": "raises", "to": "Interest rate" }
      ],
      "argument_map": [
        {
          "premise": "Persistent core inflation in the eurozone",
          "evidence": "ECB policy meeting decision",
          "conclusion": "Interest rates raised by 25 basis points"
        }
      ]
    },
    "embed_timestamp": "2024-06-15T08:01:23.456Z",
    "meta": { "executionTimeMs": 1234 }
  }
  ```
</ResponseExample>

***

## POST /api/v1/fingerprint/detect

### Request Body

Provide exactly one of `content`, `url`, or `fingerprint_id`. Content and URL queries are extracted on the fly and are never stored.

<ParamField body="content" type="string">
  Raw text to scan, typically the article you want to check. Maximum 50,000 characters.
</ParamField>

<ParamField body="url" type="string">
  URL of the document to scan.
</ParamField>

<ParamField body="fingerprint_id" type="string">
  An already-embedded fingerprint id (`fp_*`) to re-score against the registry. This reuses the stored snapshot instead of re-extracting, which makes it the cheapest option for scheduled monitoring.
</ParamField>

<ParamField body="top_k" type="number" default="5">
  Number of matches to return. Range: 1–50.
</ParamField>

<ParamField body="min_score" type="number" default="0.3">
  Minimum combined score for a candidate to be reported. Candidates with no shared signal at all are always excluded, whatever this value is. `match_found` is true only when at least one match clears both gates.
</ParamField>

<ParamField body="candidate_limit" type="number" default="1000">
  Upper bound on how many stored fingerprints are scanned, newest first. Range: 1–5000.
</ParamField>

<ParamField body="weights" type="object">
  Custom scoring weights. `entity`, `time`, and `causal` must sum to 1.0. When omitted, content-type defaults apply: news `0.5 / 0.2 / 0.3`, legal `0.3 / 0.1 / 0.6`, report `0.4 / 0.3 / 0.3`, internal `0.5 / 0.2 / 0.3`.
</ParamField>

<ParamField body="filters" type="object">
  Restrict which stored fingerprints are considered.

  <Expandable title="Filter fields">
    <ParamField body="author_id" type="string">Only this author's fingerprints</ParamField>
    <ParamField body="date_from" type="string">Inclusive lower bound on `embed_timestamp` (`YYYY-MM-DD`)</ParamField>
    <ParamField body="date_to" type="string">Inclusive upper bound on `embed_timestamp` (`YYYY-MM-DD`)</ParamField>
    <ParamField body="content_type" type="string">Only one content type</ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.factagora.com/api/v1/fingerprint/detect" \
    -H "Authorization: Bearer fa_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "content": "ECB hiked rates 25bp Thursday due to stubborn inflation.",
      "top_k": 5,
      "min_score": 0.3
    }'
  ```
</RequestExample>

### Response

<ResponseField name="match_found" type="boolean">
  True when at least one candidate cleared `min_score`.
</ResponseField>

<ResponseField name="confidence_score" type="number">
  The top match's combined score, or `0` when nothing matched.
</ResponseField>

<ResponseField name="query_fingerprint_id" type="string">
  The query's fingerprint id. For `content` and `url` queries this is minted during on-the-fly extraction and is not persisted.
</ResponseField>

<ResponseField name="matches" type="array">
  Top-K candidates, ranked by combined score descending.

  <Expandable title="Match fields">
    <ResponseField name="fingerprint_id" type="string">Matched fingerprint id</ResponseField>
    <ResponseField name="content_type" type="string">Content type recorded at embed time</ResponseField>
    <ResponseField name="metadata" type="object">Metadata stored at embed time, may be null</ResponseField>
    <ResponseField name="embed_timestamp" type="string">When the candidate was fingerprinted</ResponseField>
    <ResponseField name="score" type="number">Weighted combined score</ResponseField>
    <ResponseField name="similarity_breakdown" type="object">Per-signal scores: `entity_match`, `timeseries_match`, `causal_pattern_match`</ResponseField>
    <ResponseField name="overlap" type="object">The shared entities, time anchors, and `from|rel|to` triples behind the score</ResponseField>
    <ResponseField name="watermark_match" type="boolean">True when the input carries a watermark correlating 85% or higher with this candidate. This is near-certain provenance evidence</ResponseField>
    <ResponseField name="watermark_correlation" type="number">Bit-level correlation, null when no watermark was detected</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta" type="object">
  <Expandable title="Meta fields">
    <ResponseField name="scanned" type="number">How many stored fingerprints were scored after filters</ResponseField>
    <ResponseField name="executionTimeMs" type="number">Response time in milliseconds</ResponseField>
    <ResponseField name="weights" type="object">The weights actually applied to this request</ResponseField>
    <ResponseField name="watermark_detected" type="boolean">True when a watermark was found in the input and matched a stored fingerprint</ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "match_found": true,
    "confidence_score": 0.87,
    "query_fingerprint_id": "fp_tmpQueryId01",
    "matches": [
      {
        "fingerprint_id": "fp_l1p8OPCwGhvu",
        "content_type": "news",
        "metadata": { "author_id": "editor_jane", "source_id": "article_12345" },
        "embed_timestamp": "2024-06-15T08:01:23.456Z",
        "score": 0.87,
        "similarity_breakdown": {
          "entity_match": 0.92,
          "timeseries_match": 1.0,
          "causal_pattern_match": 0.78
        },
        "overlap": {
          "entities": ["european central bank", "interest rate", "goldman sachs"],
          "timeseries": ["2024-06-15"],
          "relations": ["european central bank|raises|interest rate"]
        },
        "watermark_match": false,
        "watermark_correlation": null
      }
    ],
    "meta": {
      "scanned": 156,
      "executionTimeMs": 342,
      "weights": { "entity": 0.5, "time": 0.2, "causal": 0.3 },
      "watermark_detected": false
    }
  }
  ```
</ResponseExample>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Embed & Detect walkthrough" icon="play" href="/guides/factagora/fingerprint/embed-and-detect">
    Step-by-step guide with code examples.
  </Card>

  <Card title="Best practices" icon="lightbulb" href="/api-reference/best-practices/fingerprint">
    Production tips for scoring, filtering, and auditing.
  </Card>
</CardGroup>
