이 페이지에서는 Mail Admin Quarantine API를 사용하여 Google Workspace 관리자 스팸 격리 저장소에 보관된 메일을 찾는 방법을 설명합니다.
API는 customers.quarantinedMessages 리소스에서 두 가지 메서드를 제공합니다.
list메서드는 필터링 없이 스팸으로 분류된 메일을 반환합니다. 이 옵션을 사용하여 스팸 격리 저장소의 모든 항목을 페이지로 표시합니다.search메서드는 구조화된 필터, Gmail 검색어 또는 둘 다를 사용하여 결과 범위를 좁힙니다. 검토 대기 중인 수신 메일만 검색하는 등 분류 워크플로에 사용합니다.
두 메서드 모두 지난 30일 동안의 메시지를 반환하고 각 메시지에 대해 동일한 기본 메타데이터를 반환합니다. 헤더, 본문, 첨부파일 또는 원시 메일을 가져오려면 메일 세부정보 가져오기를 참고하세요.
기본 요건
- API 설정의 단계를 완료했습니다.
- 관리자 스팸 격리 저장소 권한이 있는 관리자를 가장하고
https://www.googleapis.com/auth/gmail.admin.quarantine또는https://www.googleapis.com/auth/gmail.admin.quarantine.readonly범위가 포함된 액세스 토큰입니다. 도메인 전체 위임으로 승인을 참조하세요.
스팸으로 분류된 메일 나열하기
격리된 메일을 나열하려면 고객의 customers.quarantinedMessages 리소스에서 list 메서드에 GET 요청을 전송합니다.
GET https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/quarantinedMessages?pageSize=50
Authorization: Bearer ACCESS_TOKEN
CUSTOMER_ID를 고객 ID로 바꿉니다.
list 메서드는 다음 쿼리 매개변수를 허용합니다.
| 매개변수 | 설명 |
|---|---|
pageSize |
페이지당 반환할 최대 메시지 수입니다(1~300). 항상 이 파라미터를 명시적으로 설정하세요. |
pageToken |
이전 응답의 nextPageToken 값입니다. 다음 페이지를 가져오는 데 사용합니다. |
스팸으로 분류된 메일 검색하기
스팸으로 분류된 메일을 검색하려면 JSON 본문과 함께 customers.quarantinedMessages 리소스의 :search 커스텀 메서드에 POST 요청을 전송합니다.
POST https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/quarantinedMessages:search
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"filter": "status = PENDING_TRIAGE AND direction = INBOUND",
"query": "from:suspicious@example.com",
"pageSize": 50
}
요청 본문은 다음 필드를 허용합니다. 모든 필드는 선택사항입니다.
| 필드 | 설명 |
|---|---|
filter |
AIP-160 문법의 구조화된 필터입니다. 필터 문법을 참조하세요. |
query |
Gmail 검색어(예: has:attachment 또는 from:suspicious@example.com) 쿼리는 Gmail 검색창과 동일한 연산자를 사용합니다. Gmail에서 사용할 수 있는 검색 연산자를 참고하세요. |
pageSize |
페이지당 반환할 최대 메시지 수입니다(1~300). 항상 이 필드를 명시적으로 설정하세요. |
pageToken |
이전 응답의 nextPageToken 값입니다. |
filter 및 query를 모두 설정하면 API는 둘 다 일치하는 메시지만 반환합니다.
필터 구문
filter 필드는 다음 필드를 지원합니다. AND 연산자와 결합합니다. OR 및 NOT와 같은 다른 연산자는 지원되지 않습니다.
| 필드 | 지원되는 비교 | 값 |
|---|---|---|
status |
= |
PENDING_TRIAGE, RELEASED 또는 DENIED |
direction |
=, != |
INBOUND 또는 OUTBOUND. |
quarantine_name (또는 quarantineName) |
= |
Google 관리 콘솔에 표시되는 스팸 격리 저장소의 표시 이름입니다(예: "Default"). |
다음 예시에서는 유효한 필터를 보여줍니다.
status = PENDING_TRIAGE
status = PENDING_TRIAGE AND direction = INBOUND
direction != OUTBOUND AND quarantine_name = "Default"
잘못된 필터는 400 INVALID_ARGUMENT 오류를 반환합니다.
응답
두 메서드 모두 기본 메타데이터가 포함된 QuarantinedMessage 리소스 목록과 더 많은 결과를 사용할 수 있는 경우 nextPageToken를 반환합니다.
{
"quarantinedMessages": [
{
"name": "customers/01abc23de/quarantinedMessages/user@example.com:18d3ef45a8b2c1d0",
"messageId": "18d3ef45a8b2c1d0",
"messageOwner": "user@example.com",
"quarantines": [
"customers/01abc23de/quarantines/0"
],
"receiveTime": "2026-09-22T10:15:30Z",
"direction": "INBOUND",
"state": "PENDING_TRIAGE",
"retentionExpireTime": "2026-10-22T10:15:30Z",
"triggeredRules": [
{
"policyId": "123",
"ruleId": "456",
"displayName": "Inbound phishing protection"
}
]
}
],
"nextPageToken": "CAESBAgBEA..."
}
| 필드 | 설명 |
|---|---|
name |
메시지의 리소스 이름입니다. customers.quarantinedMessages 리소스에 대한 후속 get, release, deny 호출에 사용합니다. |
messageId |
변경할 수 없는 Gmail 메시지 ID입니다. |
messageOwner |
메일을 소유한 편지함의 이메일 주소입니다. |
quarantines |
메일을 보관하는 스팸 격리 저장소의 리소스 이름입니다. customers.quarantines 리소스의 get 메서드를 호출하여 스팸 격리 저장소의 표시 이름을 가져옵니다. |
receiveTime |
Gmail에서 메일을 수신한 시간 |
direction |
사용자가 메시지를 받은 경우 INBOUND, 사용자가 메시지를 보낸 경우 OUTBOUND입니다. |
state |
PENDING_TRIAGE, RELEASED 또는 DENIED |
retentionExpireTime |
스팸 격리 저장소에서 메일 보관을 중지하는 경우 |
triggeredRules |
메일이 스팸으로 분류되도록 한 규칙입니다. |
unreachable |
서비스에서 스팸으로 분류된 메일을 검색할 수 없는 계정입니다. 있는 경우 나중에 요청을 다시 시도합니다. |
결과 페이지 나누기
일치하는 모든 메시지를 검색하려면 다음 단계를 따르세요.
pageSize를 사용하여 첫 번째 요청을 전송합니다.- 응답에
nextPageToken가 포함되어 있으면 동일한 매개변수로 요청을 반복하고pageToken를 해당 값으로 설정합니다. - 응답에
nextPageToken가 포함되지 않으면 중지합니다.
다음 Python 예시에서는 분류 대기 중인 모든 인바운드 메시지를 페이지로 나눕니다.
import requests
BASE_URL = 'https://mailadminquarantine.googleapis.com/v1'
CUSTOMER_ID = '01abc23de' # Your customer ID without the leading 'C'.
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json',
}
search_url = f'{BASE_URL}/customers/{CUSTOMER_ID}/quarantinedMessages:search'
body = {
'filter': 'status = PENDING_TRIAGE AND direction = INBOUND',
'pageSize': 100,
}
messages = []
while True:
response = requests.post(search_url, headers=headers, json=body)
response.raise_for_status()
result = response.json()
messages.extend(result.get('quarantinedMessages', []))
page_token = result.get('nextPageToken')
if not page_token:
break
body['pageToken'] = page_token
print(f'Found {len(messages)} messages pending triage.')