HiAPI
블로그

튜토리얼

HiAPI 콘텐츠 정책 거부(CONTENT_POLICY_VIOLATION): 원인과 해결

이 오류 코드를 이해하고, 어디서 확인하며, 콘텐츠를 어떻게 수정해 심사를 통과하는지

Oct 22, 2026
HiAPI 콘텐츠 정책 거부(CONTENT_POLICY_VIOLATION): 원인과 해결

HiAPI의 통합 비동기 태스크 인터페이스에 생성 태스크를 제출할 때 프롬프트나 입력 소재가 보안 심사를 통과하지 못하면 비즈니스 오류 코드 CONTENT_POLICY_VIOLATION을 받게 됩니다. 공식 문서의 의미 설명은 「콘텐츠가 보안 심사를 통과하지 못함」이며, 조치 권장 사항은 「프롬프트 또는 입력 콘텐츠를 조정한 후 재시도」입니다. 이는 인증 문제도, 잔액이나 파라미터 문제도 아닙니다—콘텐츠 자체가 차단된 것입니다. 이 글에서는 이것이 어떤 모습인지, 어디서 볼 수 있는지, 그리고 어떻게 수정하는지 설명합니다.

1. 문제 현상

콘텐츠 정책 거부는 차단이 제출 단계에서 발생했는지 태스크 실행 단계에서 발생했는지에 따라 두 가지 형태로 나타납니다. CONTENT_POLICY_VIOLATION은 통합 비동기 인터페이스의 비즈니스 오류 코드이며, 태스크 생성 시의 동기 error_code와 태스크 종료 상태의 data.error.code가 동일한 열거형을 공유합니다(「생성 시점 전용」으로 표시되어 있지 않으므로 두 곳 모두에서 나타날 수 있습니다).

형태 A: 생성 시 동기적으로 거부됨. POST /v1/tasks를 호출할 때 콘텐츠가 심사를 통과하지 못하면 실패 봉투가 반환되며, error_code는 CONTENT_POLICY_VIOLATION입니다. 봉투 형태는 다음과 같습니다(공식 문서의 실패 응답 기준이며, code는 HTTP 상태, error_code는 비즈니스 코드입니다):

{
  "code": 400,
  "message": "...",
  "data": null,
  "error_code": "CONTENT_POLICY_VIOLATION"
}

이 경우 taskId를 받을 수 없습니다—태스크가 아예 생성되지 않았습니다.

형태 B: 태스크 실행 후 종료 상태가 fail. 이미 taskId를 받고 태스크가 실행된 후에야 비준수로 판정된 경우입니다. 이때 GET /v1/tasks/{taskId}를 폴링하면 HTTP는 여전히 200이고(봉투 message는 심지어 success인데, 이는 「이번 조회가 성공했다」는 의미일 뿐 태스크 성공을 의미하지 않습니다), 실제 실패는 data 안에 숨어 있습니다:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-...",
    "status": "fail",
    "error": { "code": "CONTENT_POLICY_VIOLATION", "message": "..." }
  },
  "message": "success"
}

한 줄 진단 법칙: HTTP 상태 코드만 보지 마세요. 세 계층으로 읽습니다—HTTP 상태(요청이 수락되었는가) → 비즈니스 오류 코드(error_code / data.error.code, 왜 거부되었는가) → 태스크 상태(data.status가 어디까지 진행되었는가). code 필드(동기 봉투의 error_code 또는 종료 상태의 data.error.code)가 CONTENT_POLICY_VIOLATION이면 콘텐츠 심사 차단이며, 타임아웃, 연결 끊김, 파라미터 오류와는 전혀 다릅니다. message 문구는 상황에 따라 조금씩 다를 수 있으므로, 안정적으로 판별할 수 있는 신호는 이 코드이며 message 텍스트를 정규식으로 매칭하지 마세요.

Playground / 모델 페이지의 「온라인 체험」에서 같은 종류의 차단이 발생하면, 페이지는 코드를 직접 파싱하도록 넘기는 대신 「보안 심사 미통과」라는 인라인 안내를 바로 표시합니다—이는 웹 체험(동기) 경로와 코드로 호출하는 API 경로의 표시 방식 차이입니다.

2. 일반적인 원인(발생 확률 높은 순)

  1. 프롬프트에 허용되지 않는 콘텐츠가 있음. 가장 흔합니다. NSFW / 성인, 노골적인 폭력·유혈 등의 콘텐츠는 보안 심사에서 차단됩니다. 많은 모델 자체가 명시적으로 NSFW 콘텐츠를 지원하지 않으며, 일부 모델(예: GPT Image 2)은 해당 모델 제공사의 콘텐츠 정책(예: OpenAI 콘텐츠 정책)도 따릅니다.
  2. 입력 이미지 / 참조 소재가 심사를 통과하지 못함. 이미지-투-이미지(i2i), 참조 이미지-투-비디오 같은 태스크에서는 심사 대상이 프롬프트만이 아닙니다—업로드하거나 참조한 이미지, 참조 소재도 함께 심사를 통과해야 합니다. 프롬프트는 깨끗해도 입력 이미지가 규정에 맞지 않으면 그대로 CONTENT_POLICY_VIOLATION입니다.
  3. 모델을 바꾼 후 더 엄격한 정책에 걸림. 모델마다 콘텐츠 정책의 엄격함이 다릅니다. 같은 프롬프트가 A 모델에서는 통과하고 B 모델에서는 거부되는 것은 정상이며, 특히 사실적 인물 사진, 유명인 초상, 브랜드 / 저작권 소재 같은 민감한 방향에서 그렇습니다.
  4. 거부를 다른 오류로 오판함. 실제 콘텐츠 차단을 「서비스 일시 오류」로 착각해 그대로 반복 재시도하는 경우—같은 콘텐츠는 몇 번을 재시도해도 통과하지 않으며, 기다리기만 낭비합니다.

3. 해결 단계

  1. 먼저 오류 코드를 확인하세요. 동기 응답의 error_code 또는 태스크 종료 상태의 data.error.code에서 정확한 코드를 읽습니다. CONTENT_POLICY_VIOLATION인지, TASK_FAILED(일반 실패, 대부분 일시적 문제나 입력 이미지 링크 접근 불가) 또는 INVALID_REQUEST(요청 본문 불법)가 아닌지 확인하세요. 코드가 다르면 해결 방법도 완전히 다릅니다.
  2. 프롬프트를 항목별로 정리하세요. NSFW / 성인, 노골적인 폭력 등의 표현을 제거하고 규정에 맞는 표현으로 바꿔 다시 제출합니다. 수정은 표적화되어야 하며, 아무 단어나 삭제하는 것이 아닙니다.
  3. 모든 입력 소재를 점검하세요. 이미지-투-이미지 / 참조 생성 시 심사에 걸릴 수 있는 입력 이미지, 참조 이미지를 교체하세요—프롬프트와 마찬가지로 심사를 통과해야 합니다.
  4. 대상 모델의 정책을 확인하세요. 해당 모델의 모델 페이지에서 표시된 제한을 확인하세요(예: GPT Image 2 모델 페이지에는 「NSFW 콘텐츠를 지원하지 않으며 OpenAI 콘텐츠 정책을 따름」이 명시되어 있습니다). 모델을 바꿔야 할 때는 모델 마켓에서 각 모델의 기능과 정책을 비교할 수 있습니다.
  5. 수정 후 재시도하세요. 문서에서 이 코드에 대한 조치 권장 사항은 「프롬프트 또는 입력 콘텐츠를 조정한 후 재시도」입니다. 참고: 실패한 태스크는 과금되지 않습니다—생성 시 예약된 할당량은 태스크가 실패 종료 상태에 들어간 후 전액 반환되므로, 심사에서 차단된 태스크 자체에는 비용이 발생하지 않습니다. 다만 동일한 위반 콘텐츠를 그대로 반복 제출하면 통과하지 않으므로, 먼저 수정한 후 제출하세요.

4. 최소 검증 예시

먼저 「내 key / 연동에 문제가 있는지」를 배제하고 싶다면, 명백히 규정에 맞는 프롬프트로 POST /v1/tasks를 한 번 호출해 taskId를 정상적으로 받을 수 있는지 확인하세요(model은 순수 id gpt-image-2 사용):

curl -s -X POST "https://api.hiapi.ai/v1/tasks" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "input": { "prompt": "a cozy coffee shop storefront at sunrise, warm light" }
  }'
  • {"code":200,"data":{"taskId":"tk-hiapi-..."}} 반환 → key와 연동은 정상입니다. 그렇다면 앞서 거부된 요청의 문제는 콘텐츠에 있으므로, 3절로 돌아가 프롬프트 / 입력 이미지를 정리하세요.
  • HTTP 401 + {"error":{"code":"permission_denied",...}} 반환 → 인증 문제(key 오류 / Authorization: Bearer 누락)이며 콘텐츠 정책이 아닙니다.
  • 규정에 맞는 프롬프트조차 error_code: "CONTENT_POLICY_VIOLATION" 반환 → 비교적 드문 경우입니다. 이 프롬프트에 놓친 민감한 단어가 있는지 다시 살펴보거나, 더 중립적인 설명으로 바꿔 다시 시도하세요.

5. 추가 자료

6. FAQ

Q: CONTENT_POLICY_VIOLATION과 TASK_FAILED의 차이는 무엇인가요? A: 전자는 콘텐츠가 보안 심사를 통과하지 못한 것이며, 해결 방법은 프롬프트 / 입력 소재를 수정하는 것입니다. 후자는 일반 실패이며, 가장 흔한 원인은 입력 이미지 / 동영상 URL 접근 불가 또는 일시적 변동이고, 해결 방법은 URL 수정 / 재시도입니다. 둘은 서로 다른 비즈니스 오류 코드이므로 혼동하지 마세요. error.code를 읽으면 구분할 수 있습니다.

Q: 태스크가 콘텐츠 정책으로 거부되면 과금되나요? A: 아닙니다. 문서에 따르면 태스크가 실패 종료 상태에 들어가면 생성 시 예약된 할당량이 전액 반환됩니다. 심사에서 차단된 태스크 자체는 비용을 발생시키지 않습니다.

Q: 같은 프롬프트인데 웹 「온라인 체험」에서는 명확한 「심사 미통과」 안내가 보이는데, API로는 코드만 받는 이유는 무엇인가요? A: 웹 체험은 동기 경로로 심사 결과를 인라인 안내로 직접 표시하고, API 경로는 결과를 응답 본문의 error_code / data.error.code에 담아 여러분의 코드가 읽고 분기하도록 합니다. 정보는 동일하며 표시 방식만 다릅니다.

Q: 프롬프트만 수정하고 입력 이미지는 그대로 두었는데 왜 여전히 거부되나요? A: 보안 심사는 입력 소재를 포괄하며 프롬프트만이 아닙니다. 이미지-투-이미지 / 참조 생성 시 심사에 걸릴 수 있는 입력 이미지, 참조 이미지도 함께 교체하세요.

Q: HiAPI에 공개된 「콘텐츠 정책」 페이지가 있나요? A: 별도의 콘텐츠 정책 페이지는 없습니다. 각 모델의 콘텐츠 제한은 해당 모델 페이지에 적혀 있으며(예: 「NSFW 콘텐츠를 지원하지 않음」), 플랫폼 차원의 약관은 서비스 약관과 개인정보 처리방침을 참고하세요.

Q: 반복 재시도하면 「어떻게든 통과」할 수 있나요? A: 아닙니다. 동일한 위반 콘텐츠는 몇 번을 재시도해도 통과하지 않으며, 폴링만 낭비합니다. 먼저 3절에 따라 콘텐츠를 수정한 후 제출하세요.

영구 AI 아티팩트로 빌드 시작하기

API 키를 받아 태스크 기반의 하나의 API로 이미지, 비디오, 오디오 모델을 호출하세요.

API 문서 보기