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

# Instagram 규칙 생성

> 다음 게시물에 적용되는 DM 자동화 규칙을 활성 또는 일시정지 상태로 생성합니다



## OpenAPI

````yaml api-reference/openapi.ko.yaml POST /api/preview/instagram/rules
openapi: 3.1.0
info:
  title: DocuRise 퍼블릭 API
  version: preview
  description: >
    DocuRise 프로그래매틱 접근입니다.


    **이 API는 프리뷰 단계입니다.** 모든 경로는 `/api/preview/` 하위에 버전이 지정되어 있으며,

    프리뷰 단계에서는 호환성을 보장하지 않습니다 — 필드, 값, 에러 코드가 추가, 변경 또는 제거될

    수 있습니다. 계약이 안정화되면 `/api/v1/`로 승격됩니다.

    변경 사항은 [변경 이력](/ko/changelog)에서 확인하세요.


    ### 접근 조건


    모든 라우트는 다음을 요구합니다:

    1. 유효한 API 키 (아래 인증 참고).

    2. 호출하는 계정의 요금제가 **Iconic 이상**이어야 합니다.

    3. 프리뷰 기간 동안 API는 일부 계정에서만 사용이 가능하며, 요금제와는 별개입니다.
       사용할 수 없는 계정은 아래 모든 라우트에서 `404`를 받습니다. 사용할 수 있어야
       하는 계정이라면 DocuRise 담당자에게 문의하세요.

    키 발급 및 관리는 대시보드의 **Settings → Developers**에서 할 수 있습니다.


    ### 멱등성(Idempotency)


    리소스를 생성하는 `POST` 엔드포인트는 `Idempotency-Key` 헤더가 필요합니다. 같은 키와 같은

    요청 본문으로 재요청하면 두 번째 리소스를 만드는 대신 원래 응답(동일한 상태 코드, 동일한

    본문)을 그대로 반환합니다 — 타임아웃이나 연결 끊김 시 안전하게 재시도할 수 있습니다. 키는

    7일 동안 기억되며, 그 이후에 같은 키로 요청하면 새 요청으로 처리됩니다. 같은

    키를 **다른** 본문으로 재사용하면 `IDEMPOTENCY_KEY_CONFLICT`로 거부됩니다. 매 논리적 작업마다

    새로운 키(UUID나 ULID면 충분)를 생성하세요 — HTTP 시도마다 새로 생성하지 마세요.


    예외: `POST /api/preview/tags`는 `Idempotency-Key`를 받지 않습니다. 같은 이름의 태그를 두 번

    만들어도 아무것도 바뀌지 않으므로(두 번째 호출은 기존 태그를 `created: false`로 반환), 재시도는

    항상 안전합니다.


    또 다른 예외: `POST /api/preview/segments/preview`는 `Idempotency-Key`를 받지 않습니다.

    아무것도 저장하지 않으므로 반복 호출해도 항상 안전합니다.


    ### 응답 호환성


    응답은 시간이 지나면서 필드가 추가될 수 있고, `type`/`code` 형태의 열거값(예를 들어 향후

    추가될 `LeadFormQuestion.type` 값이나 새로운 에러 `code`)도 새 값이 늘어날 수 있습니다.

    알지 못하는 필드나 열거값은 항상 무시하고 에러로 취급하지 마세요 — 이것이 `preview` 기간

    동안의 모든 추가적 변경을 하위 호환되게 만드는 원칙입니다.


    응답에서 필드가 아예 없는 것과 값이 `null`로 존재하는 것은 항상 같은 의미가 아닙니다. 타입에

    `null`이 전혀 포함되지 않는 필드는 해당하지 않을 때 아예 생략됩니다 — `null`로 전송되는 일은

    없습니다(예를 들어 `retryAfterSeconds`는 백오프 힌트가 없을 때 완전히 생략되며, `null`로

    설정되지 않습니다). 타입에 `null`을 명시적으로 허용하는 필드는 "값이 없음"과는 구분되는 실제

    의미로 `null`을 사용합니다(예를 들어 문서의 `expiresAt: null`은 "알 수 없음"이나 "해당

    없음"이 아니라, 고정 만료일이 없다는 뜻입니다).


    모든 필드명은 `notionUrl`, `leadFormQuestions`, `collectName` 등과 같이 모든 요청/응답 본문에서

    일관되게 `camelCase`를 사용합니다.


    ### 식별자


    `id` 값은 불투명한(opaque) 문자열입니다. 구조화되지 않은 토큰으로 저장하고 비교하세요 —

    파싱하거나 형식을 검증하거나 길이·문자 구성에 대해 어떤 가정도 하지 마세요.


    ### 에러


    모든 에러 응답은 동일한 형식을 갖습니다:


    ```json

    { "error": { "code": "STRING", "message": "human-readable", "retryable":
    false } }

    ```


    `message`가 아니라 `code`를 기준으로 분기하세요 — `message`는 로그/디버깅용 자유 텍스트이며

    예고 없이 문구가 바뀔 수 있습니다. `code`가 안정적인 계약입니다. `retryable`은 동일한 요청을

    그대로 재시도해도 되는지를 나타내며, 존재할 경우 `retryAfterSeconds`가 구체적인 백오프

    힌트를 제공합니다.


    요청 본문에 NUL 문자(`\u0000`)가 문자열 값이나 속성 이름에 들어 있으면 아무것도 저장하기 전에

    `400 VALIDATION_ERROR`로 거부됩니다.


    ### 속도 제한


    계정이 보유한 키 개수와 무관하게, 모든 `/api/preview/*` 라우트에 대해 계정당 분당 60회

    요청으로 제한됩니다. 초과 시 `Retry-After` 헤더와 함께 `429`가 반환됩니다.


    이와 별도로, 계정이 보유한 키 개수와 무관하게 이 라우트들에서 한 계정이 동시에 실행 중인

    요청은 최대 10개입니다. 11번째가 될 요청은 `code: TOO_MANY_CONCURRENT_REQUESTS`와

    `Retry-After: 1`이 담긴 `429`를 반환합니다. 실행 중인 요청 하나가 끝날 때까지 기다린 뒤

    재시도하세요. 이 제한은 아직 끝나지 않은 요청을 세므로, 분당 60회 이내여도 적용될 수 있습니다.
  contact:
    name: DocuRise
    url: https://docurise.io
servers:
  - url: https://docurise.io
    description: 프로덕션
security:
  - apiKey: []
tags:
  - name: Documents
    description: >-
      문서(노션 페이지, 포스트, 리드 수집 폼)를 생성하고, 내가 소유한 문서를 목록 조회하거나 읽고, 초안을 게시하며, 상태, 만료일,
      이메일 보호 설정을 변경합니다.
  - name: Analytics
    description: >-
      내 문서 하나의 조회, 방문자, 리드, 전환 집계 수치를 조회하고, 유입 채널별 분포, 이전 기간과의 비교, 폼 퍼널로도 확인하며,
      내 모든 문서를 조회, 방문자, 리드 기준으로 순위를 매겨 조회합니다.
  - name: Folders
    description: 폴더와 강의를 항목 수와 함께 조회합니다.
  - name: Products
    description: 상품 카탈로그를 조회합니다(읽기 전용).
  - name: Audiences
    description: >-
      태그와 그룹을 연락처 수와 함께 조회하고, 규칙으로 그룹을 만들고, 규칙에 맞는 연락처 수를 미리 세고, 그룹 하나를 규칙과 함께
      조회합니다. 수치만 제공하며 연락처 정보는 절대 반환하지 않습니다.
  - name: Contacts
    description: 내 연락처 하나에 태그를 추가하거나 제거합니다. 연락처 정보는 반환하지 않습니다.
  - name: Email
    description: 이메일 1회성 발송, 1회성 발송별 집계 수치, 자동화를 조회합니다. 이메일만 해당하며 카카오는 포함되지 않습니다.
  - name: Instagram
    description: Instagram 댓글-DM 자동화 규칙을 생성, 조회, 수정, 일시정지, 재개합니다.
  - name: Account
    description: 호출에 사용 중인 API 키를 확인합니다.
paths:
  /api/preview/instagram/rules:
    post:
      tags:
        - Instagram
      summary: '"다음 게시물" Instagram DM 규칙 생성하기'
      description: >
        계정의 **다음 게시물** 자동화 규칙을 생성합니다. 게시물에 달린 댓글이 규칙의 `keywords` 중

        하나와 일치하면, DocuRise가 해당 댓글에 답글을 달고 댓글 작성자에게 DM을 보냅니다.


        기본적으로 규칙은 `waiting_for_post` 상태로 생성됩니다: 아직 어떤 게시물에도 연결되지 않으며,

        **계정의 다음 새 게시물에서 자동으로 활성화**되어 이후에는 다른 규칙과 동일하게 동작합니다.

        `"status": "paused"`를 보내면 규칙이 **일시정지된 상태**로 생성됩니다: 저장되고 계정의 "다음

        게시물" 규칙 자리를 차지하지만, `PATCH /api/preview/instagram/rules/{id}`와

        `{ "status": "active" }`로 재개하기 전까지는 아무것도 전송되지 않습니다. 일시정지된 규칙에는

        `schedule.batchSendAt`을 함께 지정할 수 없습니다(`422 BATCH_RULE_NOT_PAUSABLE`,
        아무것도

        생성되지 않습니다).


        텍스트 필드(`keywords`, 답글 `variants`, `greeting`·`dm`의 메시지와 버튼 텍스트, 버튼·카드
        URL,

        `card.subtitle`)에는 NUL(U+0000) 문자를 넣을 수 없습니다. 넣으면 필드 이름이 표시된

        `400 VALIDATION_ERROR`이며 아무것도 생성되지 않습니다.


        `instagram:write` 범위와 연결된 Instagram 계정이 필요합니다.


        **계정당 "다음 게시물" 규칙은 하나뿐입니다.** 하나가 존재하는 동안(게시물을 기다리는 중이거나

        일시정지된 상태일 때) 다시 생성하면 `NEXT_POST_RULE_EXISTS`로 거부됩니다.
        `error.details.ruleId`가 그

        규칙을 알려주므로, `PATCH /api/preview/instagram/rules/{id}`로 수정하거나 대시보드에서 삭제한 뒤
        다시 시도할 수

        있습니다.


        `target`과 `type`은 선택 사항입니다: 생략하면 현재 허용되는 유일한 값인 `{ "type": "next_post"
        }`와

        `"standard"`를 보낸 것과 같습니다.


        알 수 없는 필드는 무시되지 않고 `VALIDATION_ERROR`로 거부됩니다.
      operationId: createInstagramRule
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          description: 이 생성 시도를 식별하는 클라이언트 생성 고유 문자열(255자 이하)입니다. 위의 "멱등성" 항목을 참고하세요.
          schema:
            type: string
            maxLength: 255
          example: 550e8400-e29b-41d4-a716-446655440000
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInstagramRuleRequest'
            examples:
              minimal:
                summary: 모든 댓글에 DM 하나로 응답
                value:
                  commentReply:
                    variants:
                      - Sent you a DM!
                  dm:
                    message: Here is the guide you asked for
              paused:
                summary: 공개 전에 검토할 수 있도록 일시정지 상태로 저장
                value:
                  status: paused
                  commentReply:
                    variants:
                      - Sent you a DM!
                  dm:
                    message: Here is the guide you asked for
              full:
                summary: 키워드로 시작되고 팔로우 여부를 확인하는, 링크 버튼이 있는 DM
                value:
                  target:
                    type: next_post
                  type: standard
                  keywords:
                    - guide
                    - link
                  commentReply:
                    enabled: true
                    variants:
                      - Sent you a DM!
                      - Check your DMs 📩
                  greeting:
                    enabled: true
                    message: Tap below to get the guide
                    buttonText: Send it
                  dm:
                    message: Here is the guide 👇
                    requireFollow: true
                    nonFollowerMessage: Follow us first, then tap again
                    nonFollowerButtonText: I followed
                    buttons:
                      - text: Open guide
                        url: https://docurise.io/v/my-guide
                  schedule:
                    startAt: '2026-10-01T00:00:00Z'
                    endAt: '2026-10-31T23:59:59Z'
      responses:
        '201':
          description: >-
            규칙이 생성되었습니다. 상태는 `waiting_for_post`(다음 게시물을 기다림)이거나, 일시정지로 요청했다면
            `paused`입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateInstagramRuleResponse'
        '400':
          description: |
            `VALIDATION_ERROR`(본문이 검증에 실패했습니다 — `message` 앞에 문제가 된 필드 경로가
            붙습니다. 예: `dm.message: …`), `IDEMPOTENCY_KEY_REQUIRED`,
            `IDEMPOTENCY_KEY_TOO_LONG`, `INVALID_JSON` 중 하나입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: |
            `PLAN_REQUIRED`.
            `INSUFFICIENT_SCOPE` — 키에 `instagram:write` 범위가 없습니다.
            `PAST_DUE_RESTRICTED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          $ref: '#/components/responses/NotOnAllowlist'
        '409':
          description: >
            `INSTAGRAM_NOT_CONNECTED` — 연결된 Instagram 계정이 없습니다. 먼저 대시보드에서

            연결하세요.

            `NEXT_POST_RULE_EXISTS` — "다음 게시물" 규칙이 이미 있습니다.
            `error.details.ruleId`가 그

            규칙의 id입니다.

            `IDEMPOTENCY_KEY_CONFLICT` / `IDEMPOTENCY_KEY_IN_PROGRESS` — 위의
            "멱등성" 항목을

            참고하세요.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                nextPostRuleExists:
                  value:
                    error:
                      code: NEXT_POST_RULE_EXISTS
                      message: >-
                        This account already has a next-post rule. Delete it or
                        edit it in the dashboard
                      retryable: false
                      details:
                        ruleId: 7f1c0f7e-3c5e-4b1a-9d34-2f0a5b6c8d90
        '422':
          description: >
            `BATCH_RULE_NOT_PAUSABLE` — `status`가 `paused`인데
            `schedule.batchSendAt`도 함께 보냈습니다.

            일괄 전송에는 활성 규칙이 필요합니다. 아무것도 생성되지 않았습니다. 규칙에 이미 일괄 전송이 있는 경우

            `PATCH`에서는 같은 코드가 `409`로 반환됩니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          description: '`INTERNAL_ERROR`: 예기치 않은 오류. 재시도 가능하며 원인은 반환되지 않습니다.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '502':
          description: |
            `BATCH_SCHEDULE_FAILED` — 일괄 발송(`schedule.batchSendAt`)을 예약하지 못해 규칙이
            롤백되었습니다. 같은 `Idempotency-Key`로 항상 재시도할 수 있습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          $ref: '#/components/responses/Unavailable'
      security:
        - apiKey: []
components:
  schemas:
    CreateInstagramRuleRequest:
      type: object
      required:
        - commentReply
        - dm
      properties:
        status:
          type: string
          enum:
            - active
            - paused
          default: active
          description: >
            `active`(기본값)는 규칙을 활성화해 다음 게시물을 기다리게 합니다. `paused`는 일시정지된

            상태로 저장하며, `PATCH`와 `{ "status": "active" }`로 재개하기 전까지는 아무것도 전송되지

            않습니다. `schedule.batchSendAt`과 함께 쓸 수 없습니다(`422
            BATCH_RULE_NOT_PAUSABLE`).
        target:
          type: object
          required:
            - type
          description: >-
            규칙이 적용되는 대상입니다. 선택 사항이며, 현재는 계정의 다음 새 게시물만 지원하므로 생략하면 `{ "type":
            "next_post" }`와 같습니다.
          properties:
            type:
              type: string
              enum:
                - next_post
              description: 대상의 종류입니다. 현재는 `next_post`만 지원합니다.
          additionalProperties: false
          default:
            type: next_post
        type:
          type: string
          enum:
            - standard
          default: standard
          description: 규칙 유형입니다. 선택 사항입니다. 현재 API로는 `standard`(키워드 댓글 → DM)만 생성할 수 있습니다.
        keywords:
          type: array
          maxItems: 20
          items:
            type: string
            minLength: 1
            maxLength: 50
          default: []
          description: |
            댓글이 키워드 중 하나를 **포함**하면 규칙이 작동합니다 — 대소문자를 구분하지 않는 부분
            문자열 일치이므로, `guide`는 "Guide please!"와도 일치합니다. 비어 있으면 모든 댓글에
            작동하며, 한 게시물에 키워드 규칙과 전체 댓글 규칙이 모두 있으면 키워드 규칙이 일치할 때
            키워드 규칙이 우선합니다.
        commentReply:
          type: object
          description: |
            일치하는 댓글 아래에 DocuRise가 남기는 공개 답글입니다. 댓글마다 변형 하나가 무작위로
            선택됩니다. 필수입니다 — 공개 답글을 달지 않으려면 `{ "enabled": false }`를 보내세요.
          properties:
            enabled:
              type: boolean
              default: true
              description: 일치하는 댓글 아래에 DocuRise가 공개 답글을 다는지 여부입니다. 기본값은 `true`입니다.
            variants:
              type: array
              maxItems: 10
              items:
                type: string
                minLength: 1
                maxLength: 500
              description: '`enabled`가 true이면 필수입니다(하나 이상).'
          additionalProperties: false
        greeting:
          type: object
          description: |
            첫 번째 DM으로, 이어가기 버튼 하나가 달린 메시지입니다. 댓글 작성자가 버튼을 누르면
            Instagram 메시지 창이 열리고 메인 DM이 전달됩니다. `enabled`가 false이면 메인 DM이
            비공개 답장으로 바로 발송됩니다. `message` / `buttonText`를 비워 두면 DocuRise의 기본
            문구를 사용합니다.
          properties:
            enabled:
              type: boolean
              default: true
              description: >-
                이어가기 버튼이 있는 인사 DM을 먼저 보낼지 여부입니다. `false`이면 메인 DM을 비공개 답장으로 바로
                보냅니다. 기본값은 `true`입니다.
            message:
              type: string
              maxLength: 1000
              description: >-
                인사 DM의 본문이며 최대 1000자입니다. 비워 두면 규칙의 `locale`에 맞는 DocuRise 기본 문구를
                씁니다.
            buttonText:
              type: string
              maxLength: 20
              description: 이어가기 버튼의 라벨이며 최대 20자입니다. 비워 두면 DocuRise 기본 문구를 씁니다.
          additionalProperties: false
        dm:
          type: object
          required:
            - message
          description: 댓글 작성자가 받는 메인 DM입니다.
          properties:
            message:
              type: string
              minLength: 1
              maxLength: 1000
              description: |
                최대 1000자입니다 — `card`에 이미지나 부제목이 설정된 경우에는 **80자**입니다. Instagram이
                리치 카드의 텍스트를 카드 제목으로 보내기 때문입니다. 앞뒤 공백은 제거되며, 비어 있을 수
                없습니다.
            requireFollow:
              type: boolean
              default: false
              description: |
                계정을 팔로우한 사람에게만 `message`를 보내고, 그 외의 사람에게는 `nonFollowerMessage`를
                보냅니다. `nonFollowerMessage`와 인사 단계(`greeting.enabled`)가 필요하며,
                `schedule.batchSendAt`과는 함께 쓸 수 없습니다.
            nonFollowerMessage:
              type: string
              maxLength: 1000
              description: >-
                계정을 팔로우하지 않는 댓글 작성자에게 보내는 DM이며 최대 1000자입니다. `requireFollow`가
                `true`이면 필수입니다.
            nonFollowerButtonText:
              type: string
              maxLength: 20
              description: 비팔로워가 팔로우한 뒤 누르는 버튼의 라벨입니다.
            buttons:
              type: array
              maxItems: 3
              items:
                $ref: '#/components/schemas/InstagramButton'
              default: []
              description: DM 아래에 보이는 링크 버튼이며 최대 3개입니다.
            card:
              type: object
              description: |
                이미지나 부제목(또는 둘 다)이 있는 리치 카드로 DM을 보냅니다. 둘 중 하나라도 설정되어 있는
                동안 `dm.message`는 80자로 제한됩니다.
              properties:
                imageUrl:
                  type: string
                  maxLength: 2048
                  description: >-
                    https 이미지 URL입니다. 호스트만 입력하면 `https://`로 보정되며, `http://`는
                    거부됩니다.
                subtitle:
                  type: string
                  maxLength: 80
                  description: 길이를 확인하기 전에 줄바꿈이 공백으로 바뀝니다.
              additionalProperties: false
          additionalProperties: false
        schedule:
          type: object
          description: |
            선택적 일정입니다. 운영 기간(`startAt` / `endAt`) 또는 단일 일괄 발송(`batchSendAt`) 중
            하나만 지정하며, 둘을 함께 지정할 수는 없습니다. "항상 켜짐"으로 두려면 생략하세요. "다음
            게시물" 규칙의 경우 기간은 규칙이 새 게시물에서 활성화될 때 적용되며, 그 시점에 이미 끝난
            기간은 버려지고 규칙은 그대로 시작됩니다.
          properties:
            startAt:
              type: string
              format: date-time
              description: >
                오프셋이 포함된 RFC 3339 / ISO 8601 형식입니다: `Z` 또는 숫자 오프셋

                (`2026-10-01T00:00:00Z`, `2026-10-01T09:00:00+09:00`). UTC로
                정규화되며, 응답은 항상 UTC로

                표시됩니다. 오프셋이 없는 타임스탬프(`2026-10-01T09:00:00`)는 거부됩니다.
            endAt:
              type: string
              format: date-time
              description: '`startAt`과 같은 형식입니다. `startAt`보다 늦어야 합니다(시각 기준으로 비교).'
            batchSendAt:
              type: string
              format: date-time
              description: |
                일괄 발송 모드: 일치하는 모든 댓글 작성자를 모아 이 시각에 모든 DM을 한꺼번에 발송합니다.
                `startAt`과 같은 형식이며, 미래 시각이어야 하고 6일 이내여야 합니다.
          additionalProperties: false
        locale:
          type: string
          enum:
            - en
            - ko
          description: DocuRise 기본 문구(비워 둔 인사와 버튼 텍스트)의 언어입니다. 기본값은 계정의 언어입니다.
      additionalProperties: false
    CreateInstagramRuleResponse:
      type: object
      required:
        - id
        - url
        - status
        - type
        - target
      properties:
        id:
          type: string
          format: uuid
          description: 새 규칙의 id입니다.
        url:
          type: string
          format: uri
          description: 대시보드 편집기에서 해당 규칙으로 연결되는 링크입니다.
        status:
          type: string
          enum:
            - waiting_for_post
            - paused
          description: '활성 규칙(기본값)은 `waiting_for_post`, `status: paused`로 생성했다면 `paused`입니다.'
        type:
          type: string
          description: 규칙 유형입니다. API로 만든 규칙은 `standard`입니다.
        target:
          type: object
          properties:
            type:
              type: string
              description: 대상의 종류입니다. API로 만든 규칙은 `next_post`입니다.
          description: 규칙이 적용되는 대상입니다.
      example:
        id: 7f1c0f7e-3c5e-4b1a-9d34-2f0a5b6c8d90
        url: >-
          https://docurise.io/dashboard/instagram/rules/7f1c0f7e-3c5e-4b1a-9d34-2f0a5b6c8d90
        status: waiting_for_post
        type: standard
        target:
          type: next_post
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - retryable
          properties:
            code:
              type: string
              description: 안정적인 기계 판독용 에러 코드입니다 — `message`가 아니라 이 값을 기준으로 분기하세요.
            message:
              type: string
              description: 사람이 읽을 수 있는 상세 설명입니다. 예고 없이 문구가 바뀔 수 있습니다.
            retryable:
              type: boolean
              description: 동일한 요청을 재시도했을 때 성공할 가능성이 있는지 여부입니다.
            retryAfterSeconds:
              type: integer
              description: 구체적인 백오프 힌트가 있는 경우에만 존재합니다.
            details:
              type: object
              description: >
                일부 특정 코드에만 존재합니다:

                - `PROTECTION_RULE_CONFLICT`: `{ rule: string }`, 요청을 거부한 보호
                규칙입니다
                  (`form`, `restricted_access`, `paid_lead_gate`, `free_lead_gate` 또는 `form_no_access_controls`).
                  열려 있는 값입니다. 새 값을 허용하세요.
                - `NEXT_POST_RULE_EXISTS`: `{ ruleId: string }`, 이미 있는 "다음 게시물"
                규칙입니다.

                - `NOTION_FETCH_FAILED`: `{ notionErrorCode: string }`, 다음 중
                하나입니다:
                  `NOTION_ERROR_PRIVATE`, `NOTION_ERROR_NOT_FOUND`,
                  `NOTION_ERROR_NETWORK`, `NOTION_ERROR_RATE_LIMIT`,
                  `NOTION_ERROR_TEMPORARILY_UNAVAILABLE`,
                  `NOTION_ERROR_PAGE_REJECTED`, `NOTION_ERROR_UNKNOWN`.
                - `HTML_REJECTED`: `{ reason: string }`, `too_large`,
                `css_rejected`, `invalid` 중 하나입니다.
                  열려 있는 값입니다. 새 값을 허용하세요.
                - `CONDITION_NOT_SUPPORTED`: `{ field: string, path: string }`,
                받지 않는 조건 타입과 그 조건이
                  요청에서 있는 위치입니다. 그 위치에서 거부된 조건 형태에는 `operator: string`이,
                  `requiredConditions`에서 대신 쓸 수 있는 연산자가 있으면 `invertTo: string`도 더해집니다.
                - `REFERENCE_NOT_FOUND`: `{ path: string, kind: string }`, 알 수
                없는 id가 요청에서 있는 위치와
                  그 id가 가리키는 대상(`document`, `product`, `tier`, `cta`, `folder`, `broadcast`, `step`)입니다.
                  열려 있는 값입니다. 새 값을 허용하세요.
                - `TAG_NOT_FOUND`(그룹 규칙에서): `{ tag: string }`, 존재하지 않는 태그 이름입니다.

                - `GROUP_REFERENCE_NOT_FOUND`: `{ groupIds: string[] }`, 계정에 없는
                그룹 id입니다.

                - `GROUP_LIMIT_REACHED`: `{ limit: integer }`, API로 계정이 만들 수 있는
                그룹의 최대 개수입니다.
          description: >-
            오류 정보입니다. API의 모든 오류 응답에 들어 있으며 `code`, `message`, `retryable`을 담고,
            일부 코드에는 `retryAfterSeconds`와 `details`도 담깁니다.
    InstagramButton:
      type: object
      required:
        - url
      properties:
        text:
          type: string
          maxLength: 20
          default: ''
          description: 버튼 라벨입니다.
        url:
          type: string
          maxLength: 2048
          description: >
            https 링크입니다. 호스트만 입력하면(`example.com`) `https://`로 보정되며, `http://`와 그
            밖의

            스킴은 거부됩니다.

            DocuRise 문서를 연결하려면 그 문서의 공유 `url`(문서를 생성할 때 반환된 값)을 사용하세요:

            링크 클릭 분석이 문서 버튼으로 인식합니다.
      additionalProperties: false
  responses:
    Unauthorized:
      description: '누락되었거나 형식이 잘못되었거나 폐기된 API 키입니다(`code: UNAUTHORIZED`).'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotOnAllowlist:
      description: |
        API는 일부 계정에서만 사용이 가능하며, 요금제와는 별개입니다. 사용할 수
        있어야 하는 계정이라면 DocuRise 담당자에게 문의하세요 (`code: NOT_FOUND`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: >-
        속도 제한에 걸렸습니다 (`code: RATE_LIMITED`, 항상 재시도 가능): `Retry-After` 헤더와
        `X-RateLimit-*` 헤더를 참고하세요. 또는 동시에 실행 중인 요청이 너무 많습니다 (`code:
        TOO_MANY_CONCURRENT_REQUESTS`, 항상 재시도 가능): `Retry-After`는 `1`이고
        `X-RateLimit-*` 헤더는 없습니다.
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
          description: 제한이 초기화되는 유닉스 타임스탬프(초)입니다.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unavailable:
      description: |
        서버 측 의존성이 일시적으로 다운되었습니다(`RATE_LIMIT_UNAVAILABLE` 또는
        `SERVICE_UNAVAILABLE`). 요청이나 키의 문제가 아니며, 항상 재시도 가능합니다 —
        `retryAfterSeconds`가 있으면 그에 따르세요. 그룹 엔드포인트(`POST /segments`,
        `POST /segments/preview`, `GET /segments/{id}`)는 매우 무거운 규칙의 인원을 약 10초
        안에 셀 수 없을 때도 이 코드를 반환합니다. 규칙을 단순하게 만들거나 다시 시도하세요.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: dr_live_<keyId>_<secret>
      description: |
        Settings → Developers에서 발급한 키를 `Authorization: Bearer
        dr_live_<12자리 16진수>_<64자리 16진수>` 형태로 전송합니다. 키는 명시적인 범위를
        가지며 — 각 엔드포인트에 필요한 범위가 해당 엔드포인트에 명시되어 있습니다. 전체 키는 발급 시점에 딱 한
        번만 표시되며 다시 조회할 수 없습니다 — 이후에는 `keyId` 접두어만 표시됩니다. 폐기된
        키는 바로 다음 요청부터 인증에 실패합니다.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.