메인 콘텐츠로 건너뛰기
유의 사항 X API v2용으로 batch compliance라는 새로운 컴플라이언스 도구를 출시했습니다. 이 새로운 도구를 사용하면 Post 또는 사용자 ID로 구성된 대규모 데이터 세트를 업로드하여 각 항목의 컴플라이언스 상태를 조회하고, 데이터 세트를 컴플라이언스 기준에 맞추기 위해 어떤 데이터에 조치가 필요한지 파악할 수 있습니다.
또한 batch compliance와 compliance firehose 모두 Post 편집을 지원하도록 업데이트되었습니다. compliance firehose의 경우 새로운 ‘tweet_edit’ 이벤트가 추가되었습니다. 자세한 내용은 Compliance Data Objects 문서를 참조하세요. Post 편집 메타데이터가 어떻게 동작하는지는 Edit Posts fundamentals 페이지에서 확인할 수 있습니다.

Overview

Enterprise X의 핵심 가치 중 하나는 사용자의 목소리를 보호하고 존중하는 것입니다. 여기에는 사용자가 X에서 공유하기로 선택한 콘텐츠를 삭제, 수정 또는 편집할 때 그들의 기대와 의도를 존중하는 것이 포함됩니다. 우리는 이것이 세계에서 가장 크고 공개적인 실시간 정보 플랫폼 중 하나의 장기적인 건전성을 위해 매우 중요하다고 믿습니다. X는 사용자에게 통제권을 제공하여 각 개인이 자신의 X 경험을 스스로 관리할 수 있도록 합니다. 우리는 X 데이터를 수신하는 비즈니스 고객 또한 최종 사용자의 기대와 의도를 존중할 책임이 있다고 믿습니다. X 플랫폼에서 발생할 수 있는 다양한 유형의 컴플라이언스 이벤트에 대한 자세한 내용은 문서 Honoring User Intent on X를 참고하십시오. API를 통해 X 데이터를 이용하는 모든 개발자나 회사는 사용자 콘텐츠 변경 사항을 준수하기 위해 합리적으로 가능한 모든 노력을 기울여야 할 의무가 있습니다. 이 의무는 삭제, 수정, 공유 옵션 변경(예: 콘텐츠가 보호되거나 차단되는 경우)과 같은 사용자 이벤트에까지 확장됩니다. 여기에는 사용자가 자신의 포스트를 편집하는 경우도 포함됩니다. 이 의무가 X 데이터 사용에 어떤 영향을 미치는지 이해하려면 Developer Policy 및/또는 X 데이터 계약서에 명시된 구체적인 내용을 참고하십시오. X는 이러한 사용자 컴플라이언스 이벤트와 특정 게시물 또는 사용자가 공개 상태인지 여부에 대한 정보를 제공하는 다음과 같은 솔루션을 제공합니다. 각 솔루션과 일반적인 연동 패턴에 대한 간략한 개요는 아래에 설명되어 있습니다:

GET statuses/lookup 및 GET users/lookup

  • 형식: REST API. 자세한 내용은 GET statuses/lookup 및 GET users/lookup를 참조하세요.
  • 이 엔드포인트는 항상 게시물 수정의 최신 버전을 반환합니다. 수정 기능 도입 이후에 생성된 포스트를 설명하는 모든 게시물 객체에는 게시물 수정 메타데이터가 포함됩니다. 이는 수정되지 않은 포스트에도 동일하게 적용됩니다.
  • 모든 포스트에 대해, 생성 시점으로부터 30분이 지난 후에 해당 포스트를 요청하면 그 포스트의 최종 상태를 나타냅니다.
  • 호출자가 API 요청의 일부로 정의한 특정 포스트 또는 사용자에 대한 가용성 정보를 제공합니다.
  • 특정 그룹의 포스트/사용자에 대한 현재 가용성 상태를 수시로 스팟 체크하는 용도로 사용할 수 있습니다.
  • 특정 시점에 특정 포스트 또는 사용자의 현재 상태를 확인해야 하는 고객에게 적합합니다.
  • 이러한 API는 다음과 같은 경우 콘텐츠의 가용성을 확인해야 하는 고객에게 유용한 메커니즘을 제공합니다:
    1. 포스트를 표시할 때
    2. 포스트나 사용자와 1:1 방식으로 상호작용할 때
    3. 허용된 파일 다운로드를 통해 X 콘텐츠를 제3자에게 배포할 때
    4. 포스트를 장기간 저장할 때

Compliance Firehose (엔터프라이즈 전용)

  • 형식: 스트리밍 API 자세한 내용은 Compliance Firehose를 참고하세요.
  • X에서 발생하는 컴플라이언스 활동을 실시간 스트림으로 제공합니다. 이 활동에는 게시물이 편집될 때 등이 포함됩니다. 
  • 플랫폼에서 새로운 컴플라이언스 이벤트가 발생할 때 저장된 데이터 집합 전반의 컴플라이언스 상태를 유지하는 데 사용할 수 있습니다.
  • 장기간에 걸쳐 대량의 X 데이터를 수집·저장하는 고객에게 적합합니다.

가이드

규정 준수 모범 사례

권장 사항 및 모범 사례

  • 숫자형 Post ID 및 User ID를 저장하는 데이터 저장 스키마 설계: 특정 User의 모든 게시물에 대해 조치가 필요하며, 모든 컴플라이언스 메시지는 숫자형 ID로만 전달됩니다. 따라서 숫자형 ID를 기반으로 게시물과 사용자 간의 관계를 유지하는 저장 스키마를 설계하는 것이 중요합니다. 데이터 소비자는 게시물 ID와 User ID 둘 다를 기준으로 컴플라이언스 이벤트를 모니터링하고, 로컬 데이터 저장소를 적절히 업데이트할 수 있어야 합니다.
  • 모든 컴플라이언스 상태를 다루는 스키마 설계: 다양한 애플리케이션에서 컴플라이언스 활동을 어떻게 처리하는지에 따라, 데이터 저장소에 다른 메타데이터를 추가해야 할 수 있습니다. 예를 들어, 데이터 소비자는 status_withheld 메시지의 영향을 받는 국가에서 콘텐츠 표시를 제한하기 위해 기존 데이터베이스에 메타데이터를 추가하기로 결정할 수 있습니다.
  • Retweet 삭제 처리: 리트윗(Retweet)은 원본 메시지가 리트윗 객체 내부의 중첩 객체로 포함되는 특수한 유형의 게시물입니다. 이 경우 리트윗에는 두 개의 Post ID가 참조됩니다. 리트윗 자체의 ID와 (중첩 객체에 포함된) 원본 메시지의 ID입니다. 원본 메시지가 삭제되면, 원본 ID에 대해 게시물 삭제 메시지가 발행됩니다. 게시물 삭제 이벤트는 일반적으로 모든 리트윗에 대한 삭제 이벤트를 트리거하지만, 일부 경우에는 모두 전송되지 않을 수 있으며, 클라이언트 시스템은 불완전한 리트윗 삭제 상황을 감내할 수 있도록 설계되어야 합니다. 원본 ID의 삭제만으로 이후의 모든 리트윗을 삭제하는 데 충분해야 합니다. 리트윗을 저장할 때 원본 Post ID를 함께 참조하고, 게시물 삭제 이벤트를 수신하면 참조된 모든 리트윗을 삭제하는 것이 모범 사례입니다.

컴플라이언스 데이터 객체

Compliance Firehose API

가능한 컴플라이언스 이벤트 유형에는 게시물(또는 “status”) 이벤트와 사용자(User) 이벤트가 있으며, 이들에 대해 아래에서 여러 유형을 설명합니다.   유의 사항:
  • 사용자 상태에 대한 자세한 내용은 여기에서, 삭제된 게시물에 대한 개발자 정책은 여기에서 확인할 수 있습니다.
  • Compliance Firehose는 ‘tweet_edit’ 이벤트를 제공하도록 업데이트되었습니다. 
  • 여러 사용자 삭제, 보호 및 정지 이벤트는 반드시 영구적인 것이 아니며, 상태 간에 무한히 전환될 수 있습니다. 여기에는 user_delete, user_undelete, user_protect, user_unprotect, user_suspend, user_unsuspend가 포함됩니다.
  • user_delete는 사용자가 계정을 user_undelete로 복구하지 않은 경우에만 30일 후 status_delete로 이어집니다. 사용자가 user_delete를 되돌릴 수 있으며, 이 경우 30일 후에도 해당 사용자의 모든 게시물에 대한 삭제가 발생하지 않을 수 있습니다.
  • user_suspend는 사용자가 user_unsuspend 이벤트의 대상이 되지 않는 한 true로 유지되는 조치입니다. 이 조치는 30일 기간과 관련된 어떤 변경 사항의 대상도 아닙니다.
최종 사용자의 프라이버시와 의도를 존중하면서 각 이벤트 유형을 어떻게 처리해야 하는지 이해하려면 ‘Recommended Action’ 열을 참조하세요.
Original Message TypeObjectPermanent (Yes/No)Recommended Action
deleteStatusYes연결된 게시물을 삭제합니다.
status_withheldStatusYesstatus_withheld 메시지에 나열된 특정 국가에서 연결된 게시물을 노출하지 않습니다.
dropStatusNo게시물을 공개 보기에서 제거합니다.
undropStatusNoStatus를 다시 표시할 수 있으며 공개로 취급합니다.
tweet_editStatusYes변경 사항을 반영하고, 관련 있는 경우 새로운 수정 내용을 표시합니다.
user_deleteUserNo관련 사용자가 작성한 모든 게시물을 숨기거나 삭제합니다.
user_undeleteUserNo관련 사용자가 작성한 모든 게시물을 다시 표시할 수 있으며 공개로 취급합니다.
user_protectUserNo관련 사용자가 작성한 모든 게시물을 숨기거나 삭제합니다.
user_unprotectUserNo관련 사용자가 작성한 모든 게시물을 다시 표시할 수 있으며 공개로 취급합니다.
user_suspendUserNo관련 사용자가 작성한 모든 게시물을 숨기거나 삭제합니다.
user_unsuspendUserNo관련 사용자가 작성한 모든 게시물을 다시 표시할 수 있으며 공개로 취급합니다.
scrub_geoUserYesscrub_geo 메시지에 지정된 게시물 이전에 해당 사용자가 작성한 모든 게시물에 대해, X가 제공한 모든 지리 데이터를 삭제합니다. 이후에 사용자가 작성하는 게시물에는 사용할 수 있는 지리 데이터가 포함될 수 있습니다.
user_withheldUserYesuser_withheld 메시지에 나열된 특정 국가에서 관련 사용자의 게시물을 노출하지 않습니다.
deleteFavoriteYes연결된 좋아요/즐겨찾기를 삭제합니다.

페이로드 예시

위 표에서 설명한 각 컴플라이언스 이벤트에 대한 페이로드 예시는 아래와 같습니다. 게시물 수정
{"tweet_edit":
   {
     "id": "1557445923210514432"
     "initial_tweet_id": "1557433858676740098",
     "edit_tweet_ids": ["1557433858676740098", "1557445923210514432"],
     "timestamp_ms": "1660155761384"
   }
 }
게시물 삭제
{
  "delete": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220608",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}
게시물 보류
{
  "status_withheld": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220608",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "withheld_in_countries": [
      "XY"
    ],
    "timestamp_ms": "1432228155593"
  }
}
삭제
{
  "drop": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220600",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}
삭제 취소
{
  "undrop": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220600",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}

위치 정보 삭제

{
  "scrub_geo": {
    "user_id": 519761961,
    "up_to_status_id": 411552403083628540,
    "up_to_status_id_str": "411552403083628544",
    "user_id_str": "519761961",
    "timestamp_ms": "1432228180345"
  }
}
사용자 삭제
{
  "user_delete": {
    "id": 771136850,
    "timestamp_ms": "1432228153548"
  }
}
사용자 계정 복원
{
  "user_undelete": {
    "id": 796250066,
    "timestamp_ms": "1432228149062"
  }
}
제한된 사용자
{
  "user_withheld": {
    "user": {
      "id": 1375036644,
      "id_str": "1375036644"
    },
    "withheld_in_countries": [
      "XY"
    ],
    "timestampMs": "2014-08-27T23:49:41.839+00:00"
  }
}
사용자 보호
{
  "user_protect": {
    "id": 3182003550,
    "timestamp_ms": "1432228177137"
  }
}
사용자 계정 보호 해제
{
  "user_unprotect": {
    "id": 2911076065,
    "timestamp_ms": "1432228180113"
  }
}
사용자 정지
{
  "user_suspend": {
    "id": 3120539094,
    "timestamp_ms": "1432228194217"
  }
}
사용자 계정 정지 해제
{
  "user_unsuspend": {
    "id": 3293130873,
    "timestamp_ms": "1432228193828"
  }
}

Compliance Firehose 통합하기

Compliance Firehose는 X 플랫폼에서 발생하는 컴플라이언스 이벤트를 실시간으로 전송하는 스트리밍 API입니다. X에서 컴플라이언스 이벤트가 무엇이며 어떻게 생성되는지 이해하려면, X에서 사용자 의도 존중하기 글을 참고하십시오. 게시물 및 사용자 이벤트는 서로 독립적으로 전달되며, 각각을 독립적으로 처리해야 합니다(예: 게시물 삭제가 사용자 이벤트를 의미하지 않으며, 그 반대도 마찬가지입니다). 모든 사용자 이벤트가 반드시 영구적인 것은 아니며, 상태가 계속해서 전환될 수 있습니다. 여기에는 user_delete, user_undelete, user_protect, user_unprotectuser_suspend, user_unsuspend가 포함됩니다. user_deletes는 사용자가 계정에 대해 user_undelete를 선택하지 않은 경우에만 30일 후 status_deletes가 뒤따릅니다. 사용자가 user_delete를 번복할 수 있으며, 이 경우 30일 후 해당 사용자의 모든 게시물에 대한 삭제는 발생하지 않습니다. user_suspend는 사용자가 user_unsuspend 이벤트의 대상이 되지 않는 한 계속 유지되는 조치입니다. 이는 30일 기간과 관련된 어떤 변경 규칙도 적용되지 않습니다. 컴플라이언스 이벤트를 귀하의 소프트웨어 사용자에게 직접 표시하거나, 제품이나 고객 경험에 직접 통합하는 것은 결코 적절하지 않습니다. 이 이벤트는 오로지 컴플라이언스를 준수하고 X 사용자의 행동을 존중하기 위한 목적으로만 제공됩니다.

Compliance Firehose 연동

Compliance Firehose를 시스템에 연동하려면, 다음 작업을 수행할 수 있는 통합을 구축해야 합니다:
  1. Compliance Firehose의 각 스트리밍 API 파티션에 대한 스트리밍 연결을 설정합니다.
  2. 비동기 프로세스를 사용해 스트림 수집을 후속 처리와 분리하여 대용량 데이터를 처리합니다.
  3. 어떠한 이유로든 연결이 끊어졌을 때 스트림 파티션에 자동으로 다시 연결합니다.
  4. 위에서 제시한 지침에 따라, 저장해 둔 게시물 및 사용자 데이터와 관련된 컴플라이언스 이벤트를 처리합니다.

Twitter에서 사용자의 의도를 존중하기

우리는 X 사용자의 프라이버시와 의도를 존중하는 것이, 세계에서 가장 크고 실시간으로 공개되는 정보 플랫폼 중 하나인 X의 장기적인 건전성에 결정적으로 중요하다고 믿습니다. X는 프라이버시 제어 권한을 사용자에게 부여하여 각 개인이 자신의 X 사용 경험을 스스로 제어할 수 있도록 합니다. X 데이터를 비즈니스 목적으로 사용하는 경우, 이러한 신뢰와 존중의 환경을 유지하기 위해 최종 사용자의 프라이버시와 행동을 존중해야 할 공동의 책임이 있습니다. 플랫폼에서 포스트와 사용자 계정에는 다양한 변화가 발생할 수 있으며, 이는 이들이 플랫폼에 표시되는 방식에 영향을 줍니다. 프라이버시와 의도에 영향을 미치는 조치는 Status(게시물) 수준과 User 수준 모두에서 정의됩니다. 이러한 조치에는 다음이 포함됩니다:

사용자

ActionDescription
Protect AccountX 사용자는 언제든지 자신의 계정을 보호하거나 보호 해제할 수 있습니다. 보호된 계정의 포스트를 볼 수 있는 사람은 모두 사용자가 수동으로 승인해야 합니다. 
자세한 내용은 공개 및 보호된 포스트 정보를 참조하세요.
Delete AccountX 사용자는 언제든지 자신의 계정과 그 계정과 연관된 모든 상태 메시지를 삭제할 수 있습니다. 사용자가 계정 삭제를 취소하고 계정을 다시 활성화하기로 결정하는 경우에 대비해, X는 삭제 후 30일 동안 계정 정보를 보관합니다.
Scrub GeoX 사용자는 언제든지 과거 포스트에서 모든 위치 데이터를 제거할 수 있습니다. 이를 “scrub geo”라고 합니다.
Suspend AccountX는 X 규칙을 위반한 계정이거나 계정이 해킹 또는 침해된 것으로 의심되는 경우 계정을 정지할 권리를 보유합니다. 계정 정지는 X만이 해제(정지 해제)할 수 있습니다.
Withhold AccountX는 특정 국가에서 특정 콘텐츠에 대한 액세스를 수시로 제한(보류)할 권리를 보유합니다. 보류된 계정은 X만이 보류 해제할 수 있습니다. 
자세한 내용은 국가별 보류 콘텐츠를 참조하세요.

상태

ActionDescription
게시물 삭제X 사용자는 언제든지 게시물을 삭제할 수 있습니다. 삭제된 게시물은 복구할 수 없으며 영구적으로 삭제됩니다.
게시물 제한X는 수시로 특정 국가에서 일부 콘텐츠에 대한 접근을 제한할 권리를 보유합니다. 제한된 게시물은 X만이 제한을 해제할 수 있습니다. 
자세한 내용은 국가별 차단된 콘텐츠를 참조하세요.

사용자 및 Status 변경 사항 추적

사용자(User)나 Status의 상태는 위에 나열된 작업 중 하나로 인해 언제든지 변경될 수 있으며, 이는 X 데이터를 사용하는 측에서 모든 연관 콘텐츠의 가용성과 개인정보 보호를 어떻게 처리해야 하는지에 영향을 줍니다. 이러한 작업이 발생하면 Status 또는 사용자(User)의 상태가 변경되었음을 나타내는 해당 컴플라이언스 메시지가 전송됩니다.

API 참조 문서

GET compliance/firehose

메서드

메서드설명
GET /compliance/:stream데이터 스트림에 연결

인증

Compliance Firehose API에 대한 모든 요청은 HTTP 기본 인증(HTTP Basic Authentication)을 사용해야 하며, console.gnip.com 계정에 로그인할 때 사용하는 유효한 이메일 주소와 비밀번호 조합으로 구성됩니다. 각 요청마다 이 자격 증명을 Authorization 헤더에 포함해 전달해야 합니다.

GET /compliance/:stream

Compliance firehose 데이터 스트림에 대한 지속적인 연결을 설정하며, 이를 통해 compliance 이벤트가 전달됩니다.
Request MethodHTTP GET
Connection TypeKeep-Alive
URL대시보드의 스트림 API 도움말 페이지에서 확인할 수 있으며, 다음과 유사한 구조입니다:


https://gnip-stream.x.com/stream/compliance/accounts/:account_name/publishers/twitter/:stream_label.json?partition=1

참고: “partition” 매개변수는 필수입니다. 전체 스트림을 수신하려면, 전체 볼륨의 각각 12.5%를 포함하는 8개의 모든 파티션에 연결해야 합니다.
CompressionGzip. Gzip 압축을 사용해 스트림에 연결하려면, 연결 요청에 Accept-Encoding 헤더를 포함해 전송하면 됩니다. 헤더는 다음과 같은 형식이어야 합니다:

Accept-Encoding: gzip
Character EncodingUTF-8
Response FormatJSON. 응답이 JSON 형식이 되도록 요청 헤더에서 JSON 형식을 명시해야 합니다.
Rate Limit60초당 10개의 요청.
Read TimeoutClient에 read timeout을 설정하고, 해당 값이 30초를 초과하도록 설정했는지 확인하세요.
Support for Tweet edits모든 Tweet 편집은 “tweet_edit” Compliance 이벤트를 트리거합니다. 자세한 내용은 Compliance Data Objects 문서를 참고하세요.
Example Curl Request 다음 예시 요청은 명령줄에서 cURL을 사용해 수행한 것입니다:
curl --compressed -v -uexample@customer.com "https://gnip-stream.x.com/stream/compliance/accounts/:account_name/publishers/twitter/:stream_label.json?partition=1"
참고: 위 요청은 Compliance firehose의 partition=1에만 연결되므로, 이 스트림 전체를 수신하려면 8개 모든 파티션에 연결해야 합니다.

응답 코드

이 요청에 대해 API가 다음과 같은 응답을 반환할 수 있습니다. 대부분의 오류 코드는 본문에 추가 세부 정보가 담긴 문자열 메시지와 함께 반환됩니다. 200이 아닌 응답의 경우 클라이언트는 재연결을 시도해야 합니다.
StatusTextDefinition
200Success연결이 성공적으로 열렸으며, 새로운 활동이 도착하는 대로 전송됩니다.
401Unauthorized잘못된 자격 증명으로 인해 HTTP 인증에 실패했습니다. console.gnip.com에 해당 자격 증명으로 로그인하여 요청에 올바르게 사용하고 있는지 확인하세요.
406Not Acceptable일반적으로 스트림에서 gzip 인코딩을 수락하기 위한 헤더를 클라이언트가 제대로 포함하지 않았을 때 발생하지만, 다른 상황에서도 발생할 수 있습니다. 본문에는 다음과 유사한 JSON 메시지가 포함됩니다. “이 연결에는 압축이 필요합니다. 압축을 활성화하려면 요청에 ‘Accept-Encoding: gzip’ 헤더를 포함하고, 클라이언트 측에서 스트림을 읽을 때 압축을 해제할 준비를 하세요.”
429Rate Limited앱이 연결 요청 한도를 초과했습니다.
503Service UnavailableTwitter 서버 문제입니다. 지수 백오프 패턴을 사용해 재연결하세요. 이 문제에 대한 공지가 X API 상태 페이지에 게시되지 않았다면 지원팀에 문의하세요.

기타 권장 사항 및 모범 사례

  • 숫자형 Tweet ID 및 User ID를 저장하는 데이터 저장 스키마 설계: User에 대한 메시지는 해당 User의 모든 Tweet에 대해 조치를 취해야 합니다. 따라서 모든 컴플라이언스 메시지는 숫자형 ID로만 전달되므로, 숫자형 ID를 기반으로 Tweet과 User 간의 관계를 유지하는 저장 스키마를 설계하는 것이 중요합니다. 데이터 소비자는 Tweet ID와 User ID 모두에 대해 컴플라이언스 이벤트를 모니터링하고, 로컬 데이터 저장소를 적절히 업데이트할 수 있어야 합니다.
  • 모든 컴플라이언스 상태를 처리하는 스키마 설계: 다양한 애플리케이션에서 컴플라이언스 작업을 어떻게 처리하느냐에 따라, 데이터 저장소에 다른 메타데이터를 추가해야 할 수 있습니다. 예를 들어, 데이터 소비자는 status_withheld 메시지의 영향을 받는 국가에서 콘텐츠 표시를 제한하기 위해 기존 데이터베이스에 메타데이터를 추가하도록 선택할 수 있습니다.
  • Retweet 삭제 처리: Retweet은 원본 메시지가 Retweet 내의 객체 안에 중첩되어 있는 특수한 형태의 Tweet입니다. 이 경우 Retweet에는 두 개의 Tweet ID가 참조됩니다. Retweet 자체의 ID와 (중첩 객체에 포함된) 원본 메시지의 ID입니다. 원본 메시지가 삭제되면 원본 ID에 대한 Tweet 삭제 메시지가 전송됩니다. 이후 모든 Retweet에 대해 별도의 삭제 메시지는 전송되지 않습니다. 원본 ID가 삭제되면 이후의 모든 Retweet을 삭제하는 데 충분합니다.