> ## 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

> 콘텐츠에 구조 기반 워터마크를 삽입하고 재사용을 탐지

DeepStamp는 콘텐츠가 다시 쓰이거나 번역된 뒤에도 그 출처가 당신임을 증명합니다. 삽입(embed) 단계에서 콘텐츠의 시간 지식 그래프(TKG)를 추출하고 그 구조를 씨앗으로 삼은 워터마크를 숨깁니다. 탐지(detect) 단계에서는 워터마크와 인과 구조를 함께 사용해 저장된 모든 fingerprint와 대조합니다.

<Note>
  **DeepStamp는 제품명이고, API 경로는 아직 `fingerprint`입니다.** 엔드포인트는 `/api/v1/fingerprint/embed`와 `/api/v1/fingerprint/detect`이며 응답에도 `fingerprint_id`가 사용됩니다. `/api/v1/deepstamp/*` 엔드포인트는 없습니다.
</Note>

## 엔드포인트

| 메서드    | 경로                           | 용도                              |
| ------ | ---------------------------- | ------------------------------- |
| `POST` | `/api/v1/fingerprint/embed`  | TKG 추출, 워터마크 삽입, fingerprint 저장 |
| `POST` | `/api/v1/fingerprint/detect` | 저장된 fingerprint와 대조해 점수 산출      |

***

## POST /api/v1/fingerprint/embed

### 요청 본문

`content`와 `url` 중 하나만 보냅니다.

<ParamField body="content" type="string">
  fingerprint를 생성할 원문 텍스트. 최대 50,000자.
</ParamField>

<ParamField body="url" type="string">
  fingerprint를 생성할 원본 문서의 URL.
</ParamField>

<ParamField body="content_type" type="string" default="news">
  콘텐츠 종류. `news`, `report`, `legal`, `internal` 중 하나. 탐지 시 사용할 기본 가중치도 이 값에 따라 결정됩니다.
</ParamField>

<ParamField body="metadata" type="object">
  직접 관리하는 식별자입니다. fingerprint와 함께 저장되며 매칭 결과에 그대로 반환됩니다.

  <Expandable title="Metadata fields">
    <ParamField body="author_id" type="string">내부 작성자 식별자</ParamField>
    <ParamField body="published_at" type="string">ISO 8601 발행 시각</ParamField>
    <ParamField body="source_id" type="string">CMS 기사 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>

### 응답

<ResponseField name="watermarked_content" type="string">
  TKG 기반 zero-width 워터마크가 삽입된 콘텐츠입니다. 원문 대신 이 버전을 배포하세요.
</ResponseField>

<ResponseField name="fingerprint_id" type="string">
  고유 fingerprint 식별자(`fp_*`). 내부 기사 id와 함께 보관하세요.
</ResponseField>

<ResponseField name="tkg_snapshot" type="object">
  콘텐츠에서 추출된 구조입니다.

  <Expandable title="Snapshot fields">
    <ResponseField name="entities" type="array">콘텐츠에서 추출된 개체 목록</ResponseField>
    <ResponseField name="timeseries" type="array">정규화된 시점(`YYYY`, `YYYY-MM`, `YYYY-MM-DD`)</ResponseField>
    <ResponseField name="relations" type="array">`from` / `rel` / `to` 형태의 인과·시간 관계</ResponseField>
    <ResponseField name="argument_map" type="array">전제 → 근거 → 결론 사슬</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="embed_timestamp" type="string">
  fingerprint가 삽입된 시각(ISO 8601).
</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

### 요청 본문

`content`, `url`, `fingerprint_id` 중 정확히 하나만 보냅니다. `content`와 `url`로 들어온 질의는 즉시 추출만 하고 저장하지 않습니다.

<ParamField body="content" type="string">
  검사할 원문 텍스트. 보통 확인하려는 기사 본문입니다. 최대 50,000자.
</ParamField>

<ParamField body="url" type="string">
  검사할 문서의 URL.
</ParamField>

<ParamField body="fingerprint_id" type="string">
  이미 삽입해 둔 fingerprint id(`fp_*`)를 다시 채점합니다. 저장된 스냅샷을 재사용하므로 재추출이 없고, 주기적인 모니터링에 가장 저렴한 방식입니다.
</ParamField>

<ParamField body="top_k" type="number" default="5">
  반환할 매칭 개수. 범위: 1–50.
</ParamField>

<ParamField body="min_score" type="number" default="0.3">
  결과에 포함될 최소 종합 점수입니다. 공통 신호가 전혀 없는 후보는 이 값과 무관하게 항상 제외됩니다. `match_found`는 두 조건을 모두 통과한 매칭이 하나 이상일 때만 true입니다.
</ParamField>

<ParamField body="candidate_limit" type="number" default="1000">
  최신순으로 훑을 저장된 fingerprint의 최대 개수. 범위: 1–5000.
</ParamField>

<ParamField body="weights" type="object">
  사용자 지정 가중치. `entity`, `time`, `causal`의 합이 1.0이어야 합니다. 생략하면 content\_type별 기본값이 적용됩니다. 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">
  대조할 fingerprint 범위를 좁힙니다.

  <Expandable title="Filter fields">
    <ParamField body="author_id" type="string">해당 작성자의 fingerprint만</ParamField>
    <ParamField body="date_from" type="string">`embed_timestamp` 하한(`YYYY-MM-DD`, 포함)</ParamField>
    <ParamField body="date_to" type="string">`embed_timestamp` 상한(`YYYY-MM-DD`, 포함)</ParamField>
    <ParamField body="content_type" type="string">특정 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>

### 응답

<ResponseField name="match_found" type="boolean">
  `min_score`를 통과한 후보가 하나 이상이면 true입니다.
</ResponseField>

<ResponseField name="confidence_score" type="number">
  최상위 매칭의 종합 점수입니다. 매칭이 없으면 `0`.
</ResponseField>

<ResponseField name="query_fingerprint_id" type="string">
  질의의 fingerprint id입니다. `content`나 `url` 질의의 경우 즉시 추출 과정에서 발급된 값이며 저장되지 않습니다.
</ResponseField>

<ResponseField name="matches" type="array">
  종합 점수 내림차순으로 정렬된 상위 K개 후보입니다.

  <Expandable title="Match fields">
    <ResponseField name="fingerprint_id" type="string">매칭된 fingerprint id</ResponseField>
    <ResponseField name="content_type" type="string">삽입 시점에 기록된 content\_type</ResponseField>
    <ResponseField name="metadata" type="object">삽입 시점에 저장된 metadata. null일 수 있음</ResponseField>
    <ResponseField name="embed_timestamp" type="string">해당 후보가 fingerprint된 시각</ResponseField>
    <ResponseField name="score" type="number">가중 종합 점수</ResponseField>
    <ResponseField name="similarity_breakdown" type="object">신호별 점수: `entity_match`, `timeseries_match`, `causal_pattern_match`</ResponseField>
    <ResponseField name="overlap" type="object">점수의 근거가 된 공통 개체·시점·`from|rel|to` 관계 목록</ResponseField>
    <ResponseField name="watermark_match" type="boolean">입력에 이 후보와 85% 이상 일치하는 워터마크가 있으면 true. 사실상 확정적인 출처 증거</ResponseField>
    <ResponseField name="watermark_correlation" type="number">비트 단위 상관도. 워터마크가 없으면 null</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta" type="object">
  <Expandable title="Meta fields">
    <ResponseField name="scanned" type="number">필터 적용 후 실제로 채점된 fingerprint 수</ResponseField>
    <ResponseField name="executionTimeMs" type="number">응답 시간(밀리초)</ResponseField>
    <ResponseField name="weights" type="object">이번 요청에 실제 적용된 가중치</ResponseField>
    <ResponseField name="watermark_detected" type="boolean">입력에서 워터마크를 찾아 저장된 fingerprint와 일치했으면 true</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>

***

## 다음 단계

<CardGroup cols={2}>
  <Card title="Embed & Detect 실습" icon="play" href="/ko/guides/factagora/fingerprint/embed-and-detect">
    코드 예제와 함께 단계별로 따라가는 가이드.
  </Card>

  <Card title="Best practices" icon="lightbulb" href="/ko/api-reference/best-practices/fingerprint">
    점수 산출, 필터링, 감사 로그에 대한 실전 팁.
  </Card>
</CardGroup>
