본문으로 건너뛰기

Files API

파일을 다루는 API입니다. 파일과 폴더에 공통으로 적용되는 리소스 모델, 목록 조회, 버전 이력, 잠금은 Common conventions에서 설명합니다. 이 페이지에서는 파일에만 해당하는 기능을 설명합니다.

Base URL과 scope​

/api/external/v1/files

읽기 기능에는 api:read가 필요합니다. 업로드·삭제·이름 변경·이동·복제에는 api:write도 함께 필요합니다.

Intellect용 파일 다운로드​

Intellect 전용

이 endpoint는 Intellect에서 파일을 미리 보거나 열 때 문서 내용을 불러오는 데 사용합니다. 따라서 다운로드(DOWNLOAD) 권한이 아니라 보기(VIEW) 권한을 검사합니다. 일반적인 파일 다운로드는 브라우저에서 다운로드와 같이 다운로드 토큰을 발급받아 브라우저에 전달하세요.

GET /api/external/v1/files/{resourceSeq}/download
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 불러올 파일
ssintegerNo공유 사용자 seq
Request
curl -X GET "https://drive.example.com/api/external/v1/files/{resourceSeq}/download?ss=21" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY"

성공하면 JSON 공통 구조 대신 파일을 반환합니다.

HTTP 200 OK
Content-Type: {contentType}
Content-Disposition: attachment; filename={fileName}
Content-Length: {byte}

브라우저에서 다운로드​

서버가 아니라 사용자의 브라우저에서 파일을 내려받게 하려면, 먼저 유효 시간이 짧은 다운로드 토큰을 발급받은 뒤 반환된 경로를 브라우저에 전달합니다. 토큰에 다운로드 권한이 포함되어 있으므로 두 번째 요청에는 API Key가 필요하지 않습니다.

GET /api/external/v1/files/{resourceSeq}/download-token
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 내려받을 파일
ssintegerNo공유 사용자 seq
Token response
{
"result": true,
"code": 200,
"message": "OK",
"data": {
"linkUrl": "/files/download?dt={token}"
}
}

linkUrl은 상대 경로입니다. 브라우저는 사용자가 접속한 도메인을 기준으로 이 경로를 요청합니다. 따라서 두 번째 요청은 /api/external/v1 호출이 아니며 Authorization 헤더도 보내지 않습니다.

GET https://drive.example.com/files/download?dt={dt}

위와 같은 Content-Type, Content-Disposition, Content-Length 헤더와 함께 파일 스트림을 반환합니다. /api/external/v1/files/download를 직접 호출하려면 API Key가 필요하므로 브라우저에서 다운로드할 때는 사용할 수 없습니다.

여러 리소스를 하나의 ZIP 파일로 내려받는 방법은 Common conventions의 여러 리소스 다운로드를 참고하세요.

파일 미리보기​

GET /api/external/v1/files/{resourceSeq}/view
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 미리 볼 파일
ssintegerNo공유 사용자 seq

변환된 미리보기 이미지가 아니라 원본 파일을 스트림으로 반환합니다.

HTTP 200 OK
Content-Type: {contentType}
Content-Disposition: attachment; filename={fileName}
Content-Length: {byte}

파일 업로드​

api:write 필요
POST /api/external/v1/files

파일은 multipart/form-data 형식으로 보냅니다.

파라미터Type필수설명
filefileYes업로드할 파일
pfslongNo부모 폴더 seq. st가 duplicate일 때만 사용하며, 생략하면 최상위 폴더에 업로드. 공유받은 사용자가 업로드할 때 필수
ssintegerNo공유 사용자 seq. 본인 드라이브에 업로드하면 null
stenumNo저장 방식. 대소문자 구분 없음 - duplicate(기본값)는 번호를 붙인 새 파일로 추가, version은 rs의 새 버전으로 추가, overwrite는 rs를 덮어씀
rslongNo대상 리소스 seq. st가 version 또는 overwrite일 때 필수이며, 없으면 RESOURCE_014로 실패
Request
curl -X POST "https://drive.example.com/api/external/v1/files" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-H "Content-Type: multipart/form-data" \
-F "file=@report.docx" \
-F "pfs=1"
Upload response
{
"result": true,
"code": 201,
"message": "Created",
"data": {
"resourceSeq": 283,
"resourceName": "report.docx"
}
}

version과 overwrite는 rs로 지정한 파일을 기준으로 저장하므로 pfs를 사용하지 않습니다. 계정의 저장 용량을 초과하면 QUOTA_003으로 실패합니다.

파일 이름 변경​

api:write 필요
PATCH /api/external/v1/files/{resourceSeq}/rename
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 이름을 바꿀 파일
rnstringYes새 이름
ncpenumNo이름 중복 처리 방식. 대소문자 구분 없음 - NONE(기본값)은 중복된 이름을 RESOURCE_006으로 거부, AUTO는 이름에 번호를 붙임
pfslongNo부모 폴더 seq. ncp=NONE이고 파일이 최상위 폴더에 있지 않으면 필수. 이 폴더 안에서 이름 중복을 검사하며, 생략하면 최상위 폴더를 기준으로 검사. ncp가 AUTO면 사용하지 않음
ssintegerNo공유 사용자 seq
Request
curl -X PATCH "https://drive.example.com/api/external/v1/files/{resourceSeq}/rename" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-H "Content-Type: application/json" \
-d '{"ss": 21, "rn": "quarterly-report", "ncp": "AUTO"}'

응답의 data.name은 실제로 적용된 이름이며 확장자를 포함하지 않습니다. 예를 들어 rn이 test11.docx면 name은 test11입니다. AUTO로 번호가 붙은 경우에는 rn과 다를 수 있습니다.

파일 이동​

api:write 필요
POST /api/external/v1/files/{resourceSeq}/move
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 이동할 파일
tsintegerNo대상 사용자 seq. 호출한 계정이 리소스를 공유한 사용자가 아니면 필수
pfslongNo이동할 폴더 seq. 호출한 계정이 리소스를 공유한 사용자가 아니면 필수
ssintegerNo공유 사용자 seq
Request
curl -X POST "https://drive.example.com/api/external/v1/files/{resourceSeq}/move" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-H "Content-Type: application/json" \
-d '{"ts": 1, "pfs": 367}'

파일 복제​

api:write 필요
POST /api/external/v1/files/{resourceSeq}/copy
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 복제할 파일
tsintegerNo복제 대상 사용자 seq. 호출한 계정이 리소스를 공유한 사용자면 null
pfslongNo복제할 폴더 seq. 호출한 계정이 리소스를 공유한 사용자가 아니면 필수
ssintegerNo공유 사용자 seq. 호출한 계정이 리소스를 공유한 사용자면 null

선택 헤더인 Accept-Language에 따라 복제본 이름에 붙는 문구의 언어가 정해집니다.

언어복제본 이름
ko{name}의 사본.{ext}
enCopy of {name}.{ext}
esCopia de {name}.{ext}

성공하면 201 Created와 복제본의 resourceSeq를 반환합니다. 계정의 저장 용량을 초과하면 QUOTA_003으로 실패합니다.

파일 삭제​

api:write 필요
PATCH /api/external/v1/files/{resourceSeq}/delete
파라미터Type필수설명
resourceSeqlongYespath 파라미터 - 삭제할 파일

본인 소유 파일만 삭제할 수 있으므로 ss 파라미터가 없습니다. 공유받은 파일은 RESOURCE_005로, 잠긴 파일은 RESOURCE_LOCK_ASPECT_002로 실패합니다.

삭제한 파일은 바로 제거되지 않고 휴지통으로 이동합니다. 휴지통 목록 조회·복원·영구 삭제는 Users를 참고하세요.

새 Office 문서 생성​

api:write 필요

파일을 업로드하지 않고 기본 제공 템플릿으로 빈 Word·Spreadsheet·Presentation·노트 문서를 만듭니다.

POST /api/external/v1/documents
파라미터Type필수설명
ttenumYes템플릿 유형 - word, excel, ppt, note
pfslongNo부모 폴더 seq. 본인 드라이브에서 생략하면 최상위 폴더에 생성. 공유 폴더에 만들 때(ss가 본인이 아닐 때) 필수이며, 생략하면 PERMISSION_002로 실패
ssintegerNo공유 사용자 seq. 본인 드라이브에 만들면 null

Accept-Language 헤더에 따라 사용할 템플릿과 생성되는 파일 이름이 정해집니다. 한국어(ko)·영어(en)·스페인어(es) 템플릿을 제공하며, 그 외 언어를 지정하면 템플릿이 없어 FILE_002로 실패합니다.

언어파일 이름
ko새 문서.docx, 새 프레젠테이션.pptx, 새 스프레드시트.xlsx, 새 노트.tfi
enNew Document.docx와 다른 유형의 영어 이름
esNuevo documento.docx와 다른 유형의 스페인어 이름

같은 위치에 같은 이름의 파일이 있으면 새 문서 (1).docx처럼 번호를 붙인 이름으로 생성합니다.

Request
curl -X POST "https://drive.example.com/api/external/v1/documents" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-H "Content-Type: application/json" \
-d '{"ss": 21, "pfs": 5, "tt": "word"}'
Create response
{
"result": true,
"code": 201,
"message": "Created",
"data": {
"resourceSeq": 4699,
"userSeq": 1
}
}

data.userSeq는 문서가 생성된 드라이브의 소유자 seq입니다. 공유 폴더에 만들면 요청한 계정이 아니라 폴더를 공유한 사용자의 seq입니다.

대상 폴더의 업로드(UPLOAD) 권한을 검사합니다. 실패하면 공통 실패 구조로 응답합니다.

StatuserrorCode원인
400REQUEST_001요청 값 검증 실패
403PERMISSION_001대상 폴더가 호출한 계정에 공유되지 않음
403PERMISSION_002업로드 권한 부족, 또는 공유 폴더에 pfs 누락
404RESOURCE_005대상 폴더가 존재하지 않음
404FILE_002요청한 언어의 템플릿이 없음
400QUOTA_003저장 용량 부족
Failure response
{
"result": false,
"code": 404,
"errorCode": "FILE_002",
"message": "{message}"
}

편집기 세션 endpoint​

web-office endpoint는 브라우저에서 문서를 편집하는 세션에 사용합니다. 편집기는 이 endpoint로 문서 메타데이터를 조회하고, 파일을 가져오고, 편집하는 동안 문서를 잠그고, 변경 내용을 저장하고, 잠금을 해제합니다. Thinkfree 편집기를 직접 호스팅할 때 사용합니다. SDK로 편집기를 제품에 포함하려면 Editor SDK를 참고하세요.

GET /api/external/v1/web-office/{loginUserSeq}/info
GET /api/external/v1/web-office/{loginUserSeq}/get
POST /api/external/v1/web-office/{loginUserSeq}/lock
PUT /api/external/v1/web-office/{loginUserSeq}/put
POST /api/external/v1/web-office/{loginUserSeq}/unlock
호출하는 쪽에서 사용자를 지정함

loginUserSeq는 API Key에서 가져오는 값이 아니라 호출하는 쪽에서 직접 지정하는 값입니다. 서버는 지정한 사용자가 API Key와 같은 tenant에 속하는지만 확인하며, API Key를 발급받은 계정과 같은지는 확인하지 않습니다. 따라서 API Key를 가진 쪽은 이 endpoint로 해당 tenant의 모든 사용자 권한으로 요청할 수 있습니다. 이 endpoint를 호출할 수 있는 키는 tenant 전체 권한을 가진 키로 관리하세요. 브라우저가 보낸 loginUserSeq를 그대로 전달하지 말고, 어떤 사용자로 요청할 수 있는지 서버에서 판단해야 합니다.

scope를 검사하지 않는 endpoint

편집기 세션에 사용하는 다섯 endpoint는 모두 scope 검사에서 제외됩니다. api:read만 부여된 키로도 저장 상태를 변경하는 lock, put, unlock을 호출할 수 있습니다.

공통 파라미터​

파라미터Type필수설명
loginUserSeqlongYespath 파라미터 - 편집 세션을 사용할 사용자
docIdstringYes문서 식별자. 리소스 소유자 seq와 리소스 seq를 하이픈으로 이은 값({ownerUserSeq}-{resourceSeq}, 예: 21-512)
appenumYes편집기 화면. 예: WORD_EDITOR, CELL_VIEWER, SHOW_WATCHER. info, get, put에 필수
user_idstringYes로그인 계정 이름. info, get, put에 필수
langstringNo세션 언어. 예: ko_KR. 권한 오류 메시지와 익명 사용자 표시 이름의 언어(ko, en, es)를 결정

app 값은 애플리케이션과 모드를 조합한 15가지입니다. 애플리케이션은 WORD, CELL, SHOW, HWP, PDF이고, 모드는 EDITOR, VIEWER, WATCHER입니다.

*_EDITOR는 편집(EDIT) 권한을, *_VIEWER와 *_WATCHER는 보기(VIEW) 권한을 검사합니다. 이 검사는 info, get, put에 적용되며, 문서 소유자가 요청하면 검사하지 않습니다. 공개 링크로 접속한 익명 사용자는 PUBLIC_LINK로 공유된 문서에만 접근할 수 있습니다.

문서 메타데이터 조회​

GET /api/external/v1/web-office/{loginUserSeq}/info
파라미터Type필수설명
typeenumNo요청 유형. 대소문자 구분 없음 - open(문서 열기), download(원본 다운로드), pdf_download(PDF로 변환해 다운로드), print(인쇄). download와 pdf_download는 감사 로그에 다운로드로 기록됨

JSON이 아니라 루트 요소가 <property>인 XML 문서를 반환합니다. 요청할 때 권한을 검사하며, 권한이 없으면 HTTP 403을 반환합니다. read, write, locked 필드는 실제 권한이나 잠금 상태와 관계없이 고정된 값입니다.

필드설명
type항상 file
name파일 이름. CDATA로 감싸서 반환
modified마지막 수정 일시. epoch 밀리초
read, write항상 true
locked항상 false
size파일 크기(byte)
fullName사용자 표시 이름
userCursorName요청한 user_id 값. 익명 사용자는 lang 언어로 된 익명 동물 이름
profileImage사용자 프로필 이미지
cursorColor커서 색상. 요청할 때마다 무작위로 지정
revisionmodified와 같은 값
currentVersionNumber현재 버전 번호
Request
curl -X GET "https://drive.example.com/api/external/v1/web-office/{loginUserSeq}/info?app=WORD_EDITOR&user_id={user_id}&docId=21-512&lang=ko_KR&type=open" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY"
Info response
<property>
<type>file</type>
<name><![CDATA[report.docx]]></name>
<modified>1758240000000</modified>
<read>true</read>
<write>true</write>
<locked>false</locked>
<size>24576</size>
<fullName>{fullName}</fullName>
<userCursorName>{user_id}</userCursorName>
<profileImage>{profileImage}</profileImage>
<cursorColor>{cursorColor}</cursorColor>
<revision>1758240000000</revision>
<currentVersionNumber>3</currentVersionNumber>
</property>

리소스가 없으면 HTTP 200과 함께 일반 텍스트 NotExist를 반환합니다. 따라서 상태 코드와 응답 본문을 함께 확인하세요.

문서 가져오기​

GET /api/external/v1/web-office/{loginUserSeq}/get

파일을 application/octet-stream으로 스트리밍합니다. *_VIEWER 요청은 감사 로그에 미리보기로, 그 외 app 값의 요청은 문서 열기로 기록됩니다.

Request
curl -X GET "https://drive.example.com/api/external/v1/web-office/{loginUserSeq}/get?app=WORD_EDITOR&user_id={user_id}&docId=21-512" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-o report.docx

문서 저장​

PUT /api/external/v1/web-office/{loginUserSeq}/put

문서 내용을 application/octet-stream으로 보냅니다. 성공하면 docId를 일반 텍스트로 반환합니다.

파라미터Type필수설명
app, user_id, docId-Yes공통 파라미터 참고
sizelongYes업로드할 문서의 바이트 크기
typeenumNo저장 사유. 대소문자 구분 없음. save, autoPut, close, 그 밖의 값이거나 생략하면 새 버전으로 저장. saveAs와 autoSave는 저장하지 않고 docId만 반환
openTimestamplongNo전달할 수 있지만 서버에서 사용하지 않음

다른 web-office endpoint와 달리 필수 파라미터가 없거나 형식이 잘못되면 400 REQUEST_001을 JSON으로 반환합니다. 저장 용량을 초과하면 QUOTA_003이 아니라 500 Internal Server Error를 반환합니다.

Request
curl -X PUT "https://drive.example.com/api/external/v1/web-office/{loginUserSeq}/put?app=WORD_EDITOR&user_id={user_id}&docId=21-512&size=24576&type=save" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary "@report.docx"

문서 잠금과 잠금 해제​

POST /api/external/v1/web-office/{loginUserSeq}/lock
POST /api/external/v1/web-office/{loginUserSeq}/unlock

두 endpoint 모두 docId만 사용하며 app, user_id, lang은 필요하지 않습니다. 성공하면 본문 없이 200 OK를 반환합니다. docId에 해당하는 리소스가 없으면 HTTP 400과 일반 텍스트 메시지를 반환합니다.

Request
curl -X POST "https://drive.example.com/api/external/v1/web-office/{loginUserSeq}/lock?docId=21-512" \
-H "Authorization: Bearer replace-with-your-USER-API-KEY"

편집기 세션 오류​

이 endpoint의 일부 실패 응답에는 errorCode나 본문이 없어 Errors의 코드로 원인을 구분할 수 없습니다. 상태 코드와 응답 본문을 함께 확인하세요.

경우응답
필수 파라미터 누락 또는 app 값 오류 - info, get, lock, unlockHTTP 500, 본문 없음
필수 파라미터 누락 또는 형식 오류 - put400 REQUEST_001, JSON
loginUserSeq에 해당하는 사용자 없음404 USER_005, JSON
API Key와 다른 tenant의 사용자403 AccessDenied, 일반 텍스트
docId 형식 오류500 Internal Server Error, errorCode 없는 JSON
문서 접근 권한 없음403, lang 언어로 된 권한 오류 메시지(일반 텍스트)
리소스 없음 - info200 NotExist, 일반 텍스트
리소스 없음, 파일 읽기·저장 실패, 용량 초과 - get, put500 Internal Server Error, errorCode 없는 JSON
리소스 없음 - lock, unlock400, 일반 텍스트 "리소스 잠금에 실패했습니다." / "리소스 잠금 해제에 실패했습니다."

오류​

files와 documents endpoint는 실패하면 공통 실패 구조로 응답합니다.

Failure response
{
"result": false,
"code": 400,
"errorCode": "QUOTA_003",
"message": "{message}"
}
StatuserrorCode원인
400RESOURCE_001삭제 실패
404RESOURCE_005리소스를 찾을 수 없음
409RESOURCE_006이름 중복
400RESOURCE_014rs 누락
423RESOURCE_LOCK_ASPECT_002리소스가 잠겨 있음
400QUOTA_003저장 용량 부족
500RESPONSE_001서버 오류

전체 오류 코드는 Errors를, web-office endpoint의 오류는 편집기 세션 오류를 참고하세요.