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

# 프로젝트 복제 (비동기)

> 새 프로젝트 id를 `202 Accepted`로 즉시 반환하고 복제는 서버에서 계속 진행합니다. 복제 중인 프로젝트의 상태는 `cloning`이고, 끝나면 `editing`으로 바뀝니다. 상태는 프로젝트 조회로 확인합니다.

<Warning>`cloning` 상태인 프로젝트를 편집기로 열면 로드에 실패합니다. `editing`이 된 뒤에 엽니다.</Warning>

원본이 없거나 복제할 수 없는 프로젝트는 응답 전에 걸러져 `404`나 `409`로 옵니다. 응답 뒤의 복사 단계에서 실패하면 따로 알리지 않습니다.

## 완료 콜백

`callback_url`을 주면 복제가 끝났을 때 그 주소로 JSON body를 POST합니다.

```json
{
  "partner_code": "sandbox",
  "org_project_id": "-LiBngTbCFYNjcOVcxcY",
  "new_project_id": "-LEnOT7xY0ZJgXAVfc0p",
  "src_partner_user_id": "sandbox-kr46KCD8vWOnOGo8CBO7c6ctSge2",
  "dst_partner_user_id": "sandbox-kr46KCD8vWOnOGo8CBO7c6ctSge2",
  "preview_tns": [{ "url": "https://.../1.jpg" }]
}
```

콜백을 받는 쪽은 20초 안에 2xx와 JSON body로 응답해야 합니다. 그렇지 않으면 실패로 보고 20초 간격으로 최대 3번 더 보냅니다. 복사 단계에서 실패하면 콜백이 오지 않으므로, 콜백을 기다리는 쪽은 타임아웃을 두고 프로젝트 상태를 조회합니다.



## OpenAPI

````yaml /api-reference/openapi.json post /v2/projects/{project_id}/clone_async
openapi: 3.1.0
info:
  title: Edicus Server API
  version: 1.1.5
  description: >-
    Edicus 편집기 연동에 필요한 서버 API입니다. 토큰 발급, 프로젝트 조회, 주문 처리, 폰트와 상품 정보, 템플릿 등록을
    다룹니다.


    ## 반드시 서버에서만 호출합니다


    모든 엔드포인트는 `edicus-api-key` 헤더를 요구합니다. 이 키는 고객사 서버에만 두고 브라우저 코드나 공개 저장소에 넣지
    않습니다. 브라우저에는 이 API로 발급받은 토큰만 내려보냅니다.


    ## 오류 응답


    `api.edicus.io`는 실패를 4xx와 5xx 상태 코드로 알리고, body는 언제나 `{"error": {"code",
    "message", "details", "request_id"}}` 모양입니다. `error.code`로 분기합니다. 같은
    `request_id`가 응답 헤더 `x-request-id`에도 실립니다.


    `resource-dot-edicusbase.appspot.com`은 방식이 다릅니다. 파라미터 누락은 `400`, 인증 실패는
    `401`, 그 밖의 모든 실패는 `500`이고, body에 `error` 객체가 없습니다.


    ## 응답 형식


    응답의 `content-type`은 `application/json`입니다.
  contact:
    name: 모션원
    url: https://edicus.io
servers:
  - url: https://api.edicus.io
    description: Server API 호스트
security:
  - edicusApiKey: []
tags:
  - name: Auth
    description: 토큰 발급
  - name: Projects
    description: 프로젝트 조회, 삭제, 복제
  - name: Orders
    description: 잠정 주문, 확정 주문, 취소
  - name: Fonts
    description: 폰트 그룹과 폰트 목록
  - name: Products
    description: 상품과 상품 카테고리 정보
  - name: Templates
    description: 리소스 토큰과 템플릿 패키지 등록
  - name: Resources
    description: 리소스 검색과 사용자 이미지
paths:
  /v2/projects/{project_id}/clone_async:
    post:
      tags:
        - Projects
      summary: 프로젝트 복제 (비동기)
      description: >-
        새 프로젝트 id를 `202 Accepted`로 즉시 반환하고 복제는 서버에서 계속 진행합니다. 복제 중인 프로젝트의 상태는
        `cloning`이고, 끝나면 `editing`으로 바뀝니다. 상태는 프로젝트 조회로 확인합니다.


        <Warning>`cloning` 상태인 프로젝트를 편집기로 열면 로드에 실패합니다. `editing`이 된 뒤에
        엽니다.</Warning>


        원본이 없거나 복제할 수 없는 프로젝트는 응답 전에 걸러져 `404`나 `409`로 옵니다. 응답 뒤의 복사 단계에서 실패하면
        따로 알리지 않습니다.


        ## 완료 콜백


        `callback_url`을 주면 복제가 끝났을 때 그 주소로 JSON body를 POST합니다.


        ```json

        {
          "partner_code": "sandbox",
          "org_project_id": "-LiBngTbCFYNjcOVcxcY",
          "new_project_id": "-LEnOT7xY0ZJgXAVfc0p",
          "src_partner_user_id": "sandbox-kr46KCD8vWOnOGo8CBO7c6ctSge2",
          "dst_partner_user_id": "sandbox-kr46KCD8vWOnOGo8CBO7c6ctSge2",
          "preview_tns": [{ "url": "https://.../1.jpg" }]
        }

        ```


        콜백을 받는 쪽은 20초 안에 2xx와 JSON body로 응답해야 합니다. 그렇지 않으면 실패로 보고 20초 간격으로 최대 3번
        더 보냅니다. 복사 단계에서 실패하면 콜백이 오지 않으므로, 콜백을 기다리는 쪽은 타임아웃을 두고 프로젝트 상태를 조회합니다.
      operationId: cloneProjectAsync
      parameters:
        - name: project_id
          in: path
          required: true
          description: 프로젝트 id
          schema:
            type: string
            minLength: 1
          example: '-LiBngTbCFYNjcOVcxcY'
        - name: edicus-uid
          in: header
          required: true
          description: >-
            고객사가 사용자에게 부여한 고유 id입니다. 1~70자이고 `a-z`, `A-Z`, `0-9`, `_`, `!`, `@`,
            `-`, `+`, `=`만 쓸 수 있습니다. 없거나 규칙을 어기면 `400 invalid_request`입니다.
          schema:
            type: string
            minLength: 1
            maxLength: 70
            pattern: ^[a-zA-Z0-9_!@\-+=]+$
          example: kr46KCD8vWOnOGo8CBO7c6ctSge2
        - name: edicus-target-uid
          in: header
          required: false
          description: >-
            복제본을 받을 사용자의 uid입니다. 생략하면 `edicus-uid`와 같습니다. 형식 규칙은 `edicus-uid`와
            같습니다.
          schema:
            type: string
            minLength: 1
            maxLength: 70
            pattern: ^[a-zA-Z0-9_!@\-+=]+$
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CloneAsyncBody'
            example:
              callback_url: https://partner.example.com/edicus/clone-done
      responses:
        '202':
          description: 복제를 시작했습니다. 새 프로젝트 id입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CloneAsyncResult'
              example:
                project_id: '-LEnOT7xY0ZJgXAVfc0p'
        '400':
          description: >-
            헤더가 형식 규칙을 어겼거나 `callback_url`이 `http://` 또는 `https://`로 시작하는 URL이
            아닙니다. `error.code`는 `invalid_request`입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              example:
                error:
                  code: invalid_request
                  message: 요청 형식이 맞지 않습니다
                  details:
                    issues:
                      - origin: string
                        code: invalid_format
                        format: regex
                        pattern: ^[a-zA-Z0-9_!@\-+=]+$
                        path:
                          - edicus-uid
                        message: 'allowed: a-z A-Z 0-9 _ ! @ - + ='
                  request_id: 4bf92f3577b34da6a3ce929d0e0e4736
        '401':
          description: >-
            인증 실패입니다. `error.code`는 `no_credentials`(자격 증명 헤더가 없음) 또는
            `invalid_api_key`(API 키가 틀림)입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              examples:
                invalid_api_key:
                  summary: invalid_api_key
                  value:
                    error:
                      code: invalid_api_key
                      message: edicus-api-key 값을 확인하세요
                      request_id: 4bf92f3577b34da6a3ce929d0e0e4736
                no_credentials:
                  summary: no_credentials
                  value:
                    error:
                      code: no_credentials
                      message: edicus-api-key 또는 edicus-id-token이 필요합니다
                      request_id: 4bf92f3577b34da6a3ce929d0e0e4736
        '404':
          description: 원본 프로젝트가 없습니다. `error.code`는 `project_not_found`입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              example:
                error:
                  code: project_not_found
                  message: 복제할 프로젝트가 없습니다
                  request_id: 4bf92f3577b34da6a3ce929d0e0e4736
        '409':
          description: >-
            `template_uri`가 없는 프로젝트라 복제할 수 없습니다. `error.code`는
            `project_not_clonable`입니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              example:
                error:
                  code: project_not_clonable
                  message: template_uri가 없는 프로젝트는 복제할 수 없습니다
                  request_id: 4bf92f3577b34da6a3ce929d0e0e4736
components:
  schemas:
    CloneAsyncBody:
      type: object
      properties:
        callback_url:
          type: string
          format: uri
          pattern: ^https?:\/\/
          description: 복제가 끝나면 이 주소로 POST 요청을 보냅니다. `http://` 또는 `https://`로 시작해야 합니다
    CloneAsyncResult:
      type: object
      properties:
        project_id:
          type: string
          description: 복제본의 프로젝트 id. 복제가 끝날 때까지 상태는 `cloning`입니다
      required:
        - project_id
    ErrorBody:
      type: object
      description: '`api.edicus.io`의 모든 4xx와 5xx 응답 body입니다. 클라이언트는 `error.code`로 분기합니다.'
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: snake_case 오류 코드. 이 값으로 분기합니다
              example: project_not_found
            message:
              type: string
              description: 사람이 읽는 설명입니다. 파싱하지 않습니다
            details:
              type: object
              additionalProperties: true
              description: 선택. 검증 실패면 `issues`에 어긋난 항목 목록이, 상태 충돌이면 현재 상태가 들어 있습니다
            request_id:
              type: string
              description: 요청 id입니다. 응답 헤더 `x-request-id`와 같은 값이고, 문의할 때 함께 알려 줍니다
          required:
            - code
            - message
            - request_id
      required:
        - error
      example:
        error:
          code: project_not_found
          message: 프로젝트가 없습니다
          request_id: 4bf92f3577b34da6a3ce929d0e0e4736
  securitySchemes:
    edicusApiKey:
      type: apiKey
      in: header
      name: edicus-api-key
      description: 모션원에서 발급받는 API 키입니다. 외부에 유출되지 않도록 각별히 주의합니다.

````

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