본문으로 건너뛰기

Cloud Office API Reference

Cloud Office API는 Thinkfree가 운영하는 Office에서 문서를 보거나 편집할 브라우저 세션을 만듭니다. 백엔드는 Office 서버를 직접 운영하지 않고도 계정 소유 스토리지 목록과 문서 상태를 조회하고, 브라우저에서 사용할 문서 열기 URL을 요청할 수 있습니다. 문서 열기에 성공한 뒤에는 API로 저장하거나 현재 문서를 다운로드할 수 있습니다.

API 목록​

Base URL은 https://api.thinkfree.com입니다. 아래 5개 API가 Cloud Office의 공개 API 전체입니다. 모든 API에는 Authorization 헤더가 필요합니다. 세션 생성은 같은 주소에서 두 가지 Content-Type을 받습니다.

메서드경로요청 형식성공 응답설명
GET/api/office/v1/storages본문·query 없음200, JSON (data: 배열)계정 소유 스토리지 목록 조회
POST/api/office/v1/client-sessionsJSON 또는 multipart201, JSON (data: 객체)문서 세션과 열기 URL 생성
GET/api/office/v1/client-sessions/{clientSessionId}path만 지정200, JSON (data: 객체)마지막으로 보고된 문서 상태 조회
POST/api/office/v1/client-sessions/{clientSessionId}/savepath만 지정200, JSON (data: 객체)열린 Editor 문서를 연결된 스토리지 또는 임시 저장소에 저장
GET/api/office/v1/client-sessions/{clientSessionId}/downloadpath만 지정200, 파일 바이너리열린 문서 파일을 API 호출자에게 반환

스토리지 등록·설정 변경은 Developer Console의 Storages에서 수행합니다. 위 API에는 스토리지 생성·수정·삭제나 파일 목록 조회 기능이 없습니다. 세션의 모드는 생성할 때 선택하며, 기존 Viewer를 Editor로 변경하는 API는 제공하지 않습니다.

사전 조건 및 인증​

Developer Console에서 API 키를 생성하고 서버 측 비밀 저장소에 보관합니다. 기본 만료 설정은 No expiration입니다. 만료일을 지정하면 키가 노출되었을 때 사용할 수 있는 기간을 줄일 수 있습니다. API의 날짜와 시각은 2026-08-09T02:55:00Z와 같은 ISO 8601 UTC 형식입니다.

모든 API 요청에 다음 헤더를 보냅니다.

Authorization: Bearer tfoak-replace-with-your-key
API 키는 서버에 보관하세요

브라우저 JavaScript, 모바일 앱, 문서 URL, 소스 코드, 분석 도구나 로그에 API 키를 넣지 마세요. 노출되었을 가능성이 있으면 즉시 폐기합니다. 만료되거나 폐기된 키는 인증할 수 없습니다.

공통 요청·응답 헤더​

헤더요청 필수 여부 / 생략 시 동작의미
Authorization필수. 생략하거나 사용할 수 없는 키이면 401 / 4010Bearer {API_KEY}. 상태·저장·다운로드에는 세션을 만든 동일한 키 사용
Content-Type세션 생성 때 필수스토리지 문서는 application/json, 업로드는 boundary를 포함한 multipart/form-data. 나머지 API는 본문이 없으므로 필요 없음
X-Request-ID선택. 없거나 공백뿐이거나 64자를 넘으면 서버가 UUID 생성응답의 동일한 헤더로 반환하는 요청 추적 값. 중복 요청을 방지하지 않음

각 API의 성공과 문서화된 오류 응답에는 Cache-Control: no-store, X-Request-ID, X-Thinkfree-Success, X-Thinkfree-Code, X-Thinkfree-Code-Description 헤더가 포함됩니다. 마지막 세 헤더는 JSON의 success, code, codeDescription과 같은 결과를 문자열로 표시합니다. 다운로드 성공 본문만 JSON이 아닌 바이너리입니다.

공통 JSON 응답​

모든 JSON 응답의 success는 요청의 성공 여부를 나타냅니다. 각 API가 반환하는 결과는 data에 포함됩니다.

Success
{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": {}
}
Failure
{
"success": false,
"code": 4043,
"codeDescription": "CLIENT_SESSION_NOT_FOUND",
"errorMessage": "The client session was not found",
"errorDetail": "Optional request-specific detail"
}
필드타입필수의미/허용값
successboolean필수요청 성공은 true, 실패는 false
code정수필수고정 숫자 코드. 0은 성공
codeDescription문자열필수SUCCESS, CLIENT_SESSION_NOT_FOUND 등 코드의 고정 이름
dataAPI별 타입성공 시 필수, 실패 시 생략요청한 API의 결과
errorMessage문자열실패 시 필수, 성공 시 생략실패 원인을 설명하는 메시지
errorDetail문자열선택 - 기본값: 생략추가 오류 정보. 메시지 문자열로 서비스 동작을 결정하지 않음

고객 서비스는 숫자 code로 오류를 구분합니다. 로그에는 codeDescription을 남기고, 원인을 확인할 때는 errorMessage와 errorDetail을 참고하세요.

생성 경로와 응답 그룹​

POST /api/office/v1/client-sessions는 요청의 Content-Type으로 문서 제공 방식을 구분합니다. 스토리지 문서는 application/json으로 보냅니다. 업로드 문서는 multipart/form-data의 file과 request part로 보내며, request의 Content-Type은 application/json으로 지정합니다. 두 형식 모두 clientType이 필수입니다. 브라우저에서 문서를 열려면 "BROWSER"를 지정합니다. documentSourceType은 서버가 판단해 응답에 기록하는 값입니다.

clientSessionId는 API 세션을 식별합니다. documentLifecycleId는 해당 문서의 이벤트 기록을 식별합니다. 두 ID는 별개이며, 상태 조회·저장·다운로드 주소에는 clientSessionId를 사용합니다.

응답 그룹호출 주체역할
browser.openUrl대상 사용자의 브라우저API 키 헤더 없이 Office 화면을 엽니다. 고객 서비스는 대상 사용자에게만 URL을 전달합니다.
browser.openUrlExpiresAt고객 서비스열기 URL을 처음 사용할 수 있는 마감 시각입니다. 이미 열린 Office나 API 주소의 만료 시각이 아닙니다.
api.statusUrl고객 서비스의 서버GET 요청으로 Developers가 받은 마지막 문서 상태를 조회합니다.
api.saveUrl고객 서비스의 서버POST 요청으로 문서 저장을 요청합니다. EDITOR 응답에만 포함됩니다.
api.downloadUrl고객 서비스의 서버GET으로 문서 파일을 요청할 주소입니다. 열기 성공 후 종료 전에 호출합니다.

EDITOR 모드에서는 사용자가 문서를 연 시각부터 최대 12시간 동안 편집할 수 있습니다. 12시간이 지나면 해당 세션에서 더 이상 편집할 수 없습니다. URL의 5분 기한은 문서를 처음 여는 단계에만 적용됩니다.

Office 화면의 저장·다운로드 버튼과 고객 서버의 API 호출은 서로 다른 경로입니다. Office 버튼으로 다운로드하면 사용자의 브라우저가 파일을 받습니다. 다운로드 API는 API 호출자에게 파일 바이트를 반환합니다. 상태 조회·저장·다운로드에는 세션을 만든 API 키가 필요합니다. 같은 계정의 다른 키로는 이 세션에 접근할 수 없습니다. 주소가 응답에 포함되었다고 모든 상태에서 사용할 수 있는 것은 아닙니다.

사용자·문서·세션 ID​

세션이 달라져도 사용자와 문서를 계속 식별하려면, 고객 서비스의 백엔드에서 사용자·문서 레코드와 Office에 전달할 ID의 대응 관계를 관리하세요. ID를 처음 배정할 때 해당 레코드에 저장하고, 같은 사용자가 같은 문서를 다시 열 때 재사용하세요. Office는 이 값을 사용해 공동 편집 참여자를 구분하고 문서 활동을 해당 사용자와 문서에 연결합니다.

  • userId - 고객 서비스가 지정하는 선택 요청 필드입니다. 고객 서비스의 사용자 한 명을 식별합니다. 그 사용자가 다른 세션이나 문서를 열어도 같은 값을 사용합니다. 이름·이메일·프로필 이미지가 바뀌어도 유지하며, 다른 사용자에게는 다른 값을 배정합니다.

  • docId - 고객 서비스가 지정하는 선택 요청 필드입니다. Developer Console 계정과 스토리지 연결 안에서 문서 하나를 식별합니다. 같은 문서를 다시 열거나 공동 편집할 때 같은 값을 사용하고, 다른 문서에는 다른 값을 배정합니다.

  • clientSessionId - Developers가 반환하는 응답 필드입니다. API 세션 하나를 식별합니다. userId와 docId가 같아도 세션 생성에 성공할 때마다 새 값을 반환합니다. 상태 조회·저장·다운로드 호출에는 응답으로 받은 값을 사용합니다.

  • documentLifecycleId - Developers가 반환하는 응답 필드입니다. 해당 세션의 문서 이벤트 기록을 식별합니다. 고객 서비스의 docId를 대신하지 않습니다.

userId와 docId는 선택 항목입니다. userId를 생략하면 독립된 세션 사이에 동일 사용자를 식별하는 값이 유지되지 않습니다. Developers는 고객 서비스에 로그인한 사용자를 자동으로 추론하지 않습니다. docId를 생략하면 Developers가 새 세션마다 별도의 문서 식별자를 배정합니다. 따라서 같은 경로를 다시 열어도 문서 식별자가 자동으로 유지되지 않습니다.

연결된 스토리지의 같은 문서를 여러 사람이 열거나 나중에 다시 열 때는 storageId, documentPath, docId를 일치시킵니다. 아래 사례는 모두 같은 스토리지 연결을 사용합니다.

  • Alex가 제안서를 엽니다. userId: user-1042, docId: proposal-2026-0042. 응답의 clientSessionId를 저장합니다.

  • Alex가 같은 제안서를 다시 엽니다. userId: user-1042, docId: proposal-2026-0042. 새 clientSessionId를 저장하고 userId와 docId는 유지합니다.

  • 다른 사용자가 같은 제안서의 공동 편집에 참여합니다. userId: user-2073, docId: proposal-2026-0042. 그 참여자를 위한 별도 세션을 만듭니다.

  • Alex가 다른 제안서를 엽니다. userId: user-1042, docId: proposal-2026-0043. 다른 문서의 경로를 사용해 새 세션을 만듭니다.

같은 사용자나 문서에 대해 문서를 열 때마다 새 무작위 userId나 docId를 만들지 마세요. 반대로 서로 다른 사용자에게 같은 userId를 주거나 서로 다른 문서에 같은 docId를 주면 Office가 같은 대상으로 인식하여 공동 편집 참여자나 문서 이력이 잘못 연결될 수 있습니다. 백엔드가 새 문서나 Save As로 만든 별도 사본을 여는 세션을 요청할 때는 그 문서의 docId를 사용하고 원본의 ID를 재사용하지 마세요. 원본 문서를 열 때는 기존 ID를 유지합니다.

Upload & Edit 요청은 매번 별도의 임시 원본 파일을 만듭니다. 파일 이름이나 내용이 같다는 이유로 두 업로드를 같은 문서로 간주하지 마세요. 별도로 업로드한 사본에는 별도 문서 ID를 배정합니다. 이전 업로드나 편집 내용을 되찾는 용도로 docId를 재사용하지 마세요. 이 API는 docId로 이전 업로드를 다시 여는 기능을 제공하지 않습니다. 여러 참여자가 같은 저장 문서를 반복해서 열어야 한다면 연결된 스토리지를 사용하세요.

이 ID는 사용자와 문서를 구분하는 값이며 사용자 인증이나 문서 접근 권한을 대신하지 않습니다. 고객 서비스의 백엔드는 세션을 만들기 전에 사용자를 인증하고 해당 문서의 접근 권한을 확인해야 합니다.

스토리지 연결 목록 조회​

API 역할​

GET /api/office/v1/storages는 API 키 계정이 소유한 스토리지 연결의 요약을 반환합니다. 비밀정보는 응답에서 제외합니다. 브라우저 클라이언트 세션을 생성할 때 반환된 storageId를 사용합니다. ACTIVE 연결만 문서를 열 수 있습니다.

요청​

curl --fail-with-body \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
https://api.thinkfree.com/api/office/v1/storages
필드위치타입필수의미/허용값
Authorization헤더문자열예Bearer {API_KEY}
X-Request-ID헤더문자열아니요 - 기본값: 서버 생성 UUID요청을 추적할 ID, 최대 64자

응답​

{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": [
{
"storageId": "74a73536-3024-48c2-a850-76cf7872323f",
"name": "Production documents",
"description": "Documents used by the production service",
"type": "S3",
"status": "ACTIVE"
}
]
}
필드타입필수의미/허용값
data배열필수스토리지 연결 목록. 연결이 없으면 빈 배열
data[].storageIdUUID 문자열필수변경되지 않는 스토리지 ID. 세션 생성 요청의 storageId로 전달
data[].name문자열필수수정 가능한 표시 이름, 1~100자. API 식별자로 사용하지 않음
data[].description문자열필수스토리지 용도를 설명하는 문구, 1~200자
data[].type문자열 enum필수S3, S3_COMPATIBLE, WEBDAV
data[].status문자열 enum필수PROVISIONING, ACTIVE, SYNC_FAILED, DELETING, DELETE_FAILED

자격 증명, 공급자 토큰, 버킷, 엔드포인트 및 접두사는 반환되지 않습니다. 이 API에 대한 오류는 4010 INVALID_API_KEY 및 5001 STORAGE_ADAPTER_LIST_FAILED입니다.

type은 S3(Amazon S3), S3_COMPATIBLE(S3 호환 Object Storage), WEBDAV 중 하나입니다. status는 ACTIVE(사용 가능), PROVISIONING(등록 중), SYNC_FAILED(설정 반영 실패), DELETING(삭제 중), DELETE_FAILED(삭제 실패) 중 하나입니다. ACTIVE가 아니면 세션을 만들지 말고 Console의 Storages에서 연결 상태를 확인하세요. 이 상태는 개별 파일의 존재나 스토리지의 순간적인 응답 여부를 보장하지 않습니다.

이 요청에는 path parameter, query parameter, 요청 본문과 페이지 번호가 없습니다. 응답은 목록 전체이며, 연결이 없으면 data: []를 반환합니다.

브라우저 클라이언트 세션 생성​

API 역할​

POST /api/office/v1/client-sessions는 계정 소유의 활성 스토리지 연결을 확인한 다음 브라우저 클라이언트 세션을 만듭니다. 응답에는 선택한 모드로 Cloud Office 문서를 여는 URL 하나와 문서 상태를 조회할 정보가 포함됩니다. 요청에 사용한 API 키와 스토리지는 같은 계정에 속해야 합니다.

스토리지 문서 크기 제한은 Word, Cell, Show 모두 300 MB(314,572,800바이트, 300 MiB)입니다. 크기가 제한 이내라도 Office가 지원하고 처리할 수 있는 형식과 내용이어야 합니다. multipart 업로드 제한은 별도로 100 MB(104,857,600바이트, 100 MiB)입니다.

링크를 만들 때는 크레딧을 차감하지 않으며 creditsCharged: 0을 반환합니다. 문서 열기가 성공하면 뷰어는 5크레딧, 편집기는 10크레딧을 차감합니다. 열기에 실패하면 차감하지 않습니다. 링크 발급 전에는 선택한 모드에 따라 뷰어(VIEWER)는 5크레딧, 에디터(EDITOR)는 10크레딧을 사용할 수 있는지 확인하며, 후불 사용에 동의한 계정은 허용 한도 내 초과 사용량을 포함합니다. 사용할 수 있는 크레딧이 부족하면 HTTP 402 / 4020 INSUFFICIENT_CREDIT를 반환합니다.

요청​

curl --fail-with-body \
-X POST https://api.thinkfree.com/api/office/v1/client-sessions \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
-H "Content-Type: application/json" \
-d '{
"clientType": "BROWSER",
"mode": "EDITOR",
"storageId": "74a73536-3024-48c2-a850-76cf7872323f",
"documentPath": "proposals/proposal-2026-0042.docx",
"userId": "user-1042",
"docId": "proposal-2026-0042",
"fileDisplayName": "customer-proposal.docx",
"userDisplayName": "Alex Kim",
"userEmail": "alex@example.com",
"userAvatarUrl": "https://example.com/profiles/alex.png",
"language": "en_US",
"skin": "default"
}'
필드위치타입필수의미/허용값
Authorization헤더문자열예Bearer {API_KEY}
Content-Type헤더문자열예application/json
X-Request-ID헤더문자열아니요 - 기본값: 서버 생성 UUID요청을 추적할 ID, 최대 64자
clientType본문문자열 enum필수BROWSER
mode본문문자열 enum필수 - 기본값 없음VIEWER는 읽기 전용, EDITOR는 편집·저장
storageId본문UUID 문자열필수API 키 계정이 소유한 활성 스토리지의 ID
documentPath본문문자열필수스토리지 루트 기준 상대 경로와 파일 이름. 최대 1,024자
fileDisplayName본문문자열선택 - 기본값: documentPath의 마지막 파일 이름Office에 표시할 이름, 최대 255자. 확장자로 문서 앱을 선택하며 원본 경로는 바꾸지 않음. 경로 구분자·제어 문자 또는 이름 전체가 .·..인 값은 허용하지 않음
userId본문문자열선택 - 생략하면 세션마다 별도 익명 사용자로 식별1~128자. Unicode 문자·숫자, 공백과 ._@+()- 허용. 같은 사용자에게는 같은 값, 다른 사용자에게는 다른 값 사용. 프로필 변경과 독립적
userDisplayName본문문자열선택 - 기본값: 생략표시 이름, 최대 256자. 사용자 식별자로 사용하지 않음
userEmail본문문자열선택 - 기본값: 생략프로필 이메일, 최대 254자. 인증에 사용하지 않음
userAvatarUrl본문HTTPS URL 문자열선택 - 기본값: 생략인증 없이 누구나 읽을 수 있는 공개 HTTPS 이미지 주소. 최대 2,048자이며 URL의 인증정보와 fragment는 허용하지 않음. Beta: Office가 아직 이 이미지를 사용자 프로필 아이콘으로 표시하지 않습니다.
docId본문문자열선택 - 기본값: 새 세션마다 생성1~48자. ASCII 영문·숫자·_·- 허용. 같은 문서에는 같은 값, 다른 문서에는 다른 값 사용
language본문문자열선택 - 입력하지 않으면 Office 요청에서 생략각각 2~8자인 ASCII 영문 두 묶음을 _로 연결. 예: en_US, ko_KR. 생략 시 Office의 언어 설정 사용
skin본문문자열선택 - 입력하지 않으면 Office 요청에서 생략1~32자인 ASCII 영문·숫자·_·-. 생략 시 Office의 스킨 설정 사용

경로는 /로 구분하며, 스토리지에 설정한 루트를 기준으로 작성합니다. 상위 경로로 이동하는 .., 버킷 이름, endpoint나 자격 증명을 넣지 마세요. 지원되는 파일 형식은 doc, docx, odt, xls, xlsx, ods, ppt, pptx 및 odp입니다.

예제는 Alex에게 user-1042, 저장된 제안서에 proposal-2026-0042를 배정합니다. 고객 서비스의 사용자·문서 레코드에 연결한 값으로 바꾸고, 이 문서를 다시 열 때 같은 값을 재사용하세요. 공동 편집에서는 모든 참여자가 같은 스토리지, 경로, docId를 사용하고 참여자마다 자신의 userId를 사용합니다. ID 재사용과 세션 사례를 참고하세요. language와 skin은 입력한 경우에만 Office로 전달합니다.

fileDisplayName의 확장자로 문서 앱을 선택합니다. 저장소 경로에 확장자가 없다면 실제 파일 형식에 맞는 fileDisplayName을 지정하세요. 이 이름은 원본 경로나 파일 형식을 변경하지 않습니다.

선택 필드와 문자열 입력​

요청 표에 명시된 필드명만 사용하세요. JSON 본문이나 multipart의 request에 지원하지 않는 필드명이 있으면 API는 해당 필드를 무시하지 않고 요청 전체를 HTTP 400, 코드 4001 INVALID_DOCUMENT_REQUEST로 거절합니다.

필수 필드에는 null, 빈 문자열이나 공백만 있는 값을 보내지 마세요. 선택 문자열은 생략하거나 null로 보내면 표에 적힌 생략 동작을 따릅니다. userId, docId, language, skin은 앞뒤 공백을 제거하며 공백뿐이면 생략한 것으로 취급합니다. 프로필 필드도 앞뒤 공백을 제거하지만, 길이 초과나 제어 문자가 있는 값은 거절합니다. userEmail은 이메일 주소 형식이어야 합니다.

fileDisplayName이 없거나 공백뿐이면 문서 경로나 multipart 파일 이름을 사용합니다. 파일 이름은 앞뒤 공백을 제거하고 Unicode NFC로 정규화합니다. 이 동작은 저장소의 실제 파일 이름을 변경하지 않습니다. documentPath는 저장소 루트를 기준으로 /로 구분한 경로를 보내세요. 서버는 앞뒤 공백과 /를 제거하고 \를 /로 변환합니다. . 또는 ..인 경로 요소는 거절합니다. URL이 아닌 경로 문자열이므로 JSON 안의 공백이나 한글을 URL 인코딩하지 마세요.

응답​

HTTP 201 Created는 세션을 만들었다는 뜻이며 Office에서 문서 열기에 성공했다는 뜻은 아닙니다. 생성한 세션은 응답 본문의 data.clientSessionId와 data.api.statusUrl로 식별하며, 이 endpoint는 Location 헤더를 반환하지 않습니다.

{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": {
"clientSessionId": "9169250d-5328-4d45-844b-9a37cb52f7ac",
"clientType": "BROWSER",
"documentSourceType": "STORAGE",
"documentLifecycleId": "0d102ee8-cbdd-4667-a5cf-f2e3a1007927",
"mode": "EDITOR",
"status": "CREATED",
"creditsCharged": 0,
"createdAt": "2026-08-08T14:55:00Z",
"browser": {
"openUrl": "https://office.developers.thinkfree.com/cloud-office/api/open-document?ticket=<ticket>",
"openUrlExpiresAt": "2026-08-08T15:00:00Z"
},
"api": {
"statusUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac",
"saveUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/save",
"downloadUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/download"
}
}
}
필드타입필수의미/허용값
data.clientSessionIdUUID 문자열필수생성한 클라이언트 세션의 ID. 상태 조회·저장·다운로드 요청에 사용
data.clientType문자열 enum필수항상 BROWSER
data.documentSourceType문자열 enum예STORAGE; 요청한 Storage Connection에서 가져온 문서입니다. 뷰어/편집기 모드와는 별개입니다.
data.documentLifecycleIdUUID 문자열필수문서의 열기·저장·종료 이벤트 기록을 구분하는 ID. clientSessionId와 별도 값
data.mode문자열 enum필수요청에서 선택한 VIEWER 또는 EDITOR
data.browser객체BROWSER 응답에 필수브라우저에서 Office를 열 때 사용할 정보
data.browser.openUrlHTTPS URL 문자열필수선택한 모드로 문서를 여는 일회용 URL
data.browser.openUrlExpiresAtISO 8601 UTC 문자열필수발급 후 5분인 최초 열기 마감 시각. 이미 열린 문서나 API 사용 기한과는 별개
data.api객체필수세션을 만든 API 키로 호출할 주소 묶음
data.api.statusUrlHTTPS URL 문자열필수Office가 보고한 문서 상태를 조회할 주소. 세션을 만든 API 키 필요
data.api.saveUrlHTTPS URL 문자열EDITOR일 때만 필수, VIEWER는 생략문서 저장 요청 주소. Editor로 열기에 성공한 뒤 고객 서비스의 백엔드에서 호출
data.api.downloadUrlHTTPS URL 문자열필수문서 다운로드 요청 주소. 열기 성공 후 종료 전까지 호출
data.status문자열 enum필수초기값 CREATED. 이후 상태는 api.statusUrl로 조회
data.creditsCharged정수필수세션 생성 요청에서 차감한 크레딧. 문서 열기 성공 시 과금하므로 생성 응답은 0
data.createdAtISO 8601 UTC 문자열필수클라이언트 세션을 만든 시각

Office는 요청에 지정한 사용자 식별자, 선택 프로필, 문서 정보, 언어와 스킨을 사용합니다. 이 값들은 응답에 다시 넣지 않습니다. userDisplayName, userEmail, userAvatarUrl이 바뀌어도 userId는 유지하세요. 선택 프로필 필드에는 제어 문자를 넣을 수 없으며, 공백만 입력하면 생략한 것으로 처리합니다.

userAvatarUrl의 이미지는 로그인·인증 헤더·인증 쿠키 없이 누구나 읽을 수 있어야 합니다. 이 필드는 Beta이며, Office 프로필 아이콘 표시에는 아직 적용되지 않습니다.

확장자뷰어 애플리케이션에디터 애플리케이션
doc, docx, odtWord 뷰어Word 편집기
xls, xlsx, odsCell 뷰어Cell 편집기
ppt, pptx, odpShow 뷰어Show 편집기

오류 코드는 4001 INVALID_DOCUMENT_REQUEST, 4010 INVALID_API_KEY, 4020 INSUFFICIENT_CREDIT, 4021 SUBSCRIPTION_ACCESS_UNAVAILABLE, 4041 STORAGE_CONNECTION_NOT_FOUND, 4150 UNSUPPORTED_MEDIA_TYPE, 5021 STORAGE_UNAVAILABLE, 5022 OFFICE_OPEN_URL_UNAVAILABLE입니다. 생성 API가 지원하지 않는 Content-Type에는 HTTP 415 / 4150을 반환합니다.

browser.openUrlExpiresAt 이전에 browser.openUrl을 여세요. 이 URL은 한 번만 사용할 수 있습니다. 티켓이 만료되었거나 이미 사용했다면 새 브라우저 클라이언트 세션을 요청하세요. 뷰어는 문서를 읽기 전용으로 엽니다. 문서 열기 URL을 로그, 분석 도구 또는 지원 메시지에 포함하지 마세요.

browser.openUrl을 가진 사람은 문서를 열 수 있으므로, 고객 서비스는 대상 사용자의 브라우저에만 이 URL을 전달해야 합니다. URL을 로그, 분석 도구, referrer 또는 지원 메시지에 남기지 마세요. Office에서 저장한 문서는 연결된 스토리지에 반영됩니다. API 저장·다운로드의 접근 조건은 아래에서 확인하세요.

브라우저 클라이언트 세션 업로드 및 생성​

API 역할​

POST /api/office/v1/client-sessions에 파일을 업로드하면 Cloud Office 브라우저 클라이언트 세션을 만듭니다. 스토리지 연결이 필요하지 않습니다. 애플리케이션이 파일을 보내서 단기 편집 세션을 만들 때 사용하세요. API 저장·다운로드는 열기 성공 후 종료 전에 호출합니다.

링크를 만들 때는 크레딧을 차감하지 않으며 creditsCharged: 0을 반환합니다. 문서 열기가 성공하면 뷰어는 5크레딧, 편집기는 10크레딧을 차감합니다. 열기에 실패하면 차감하지 않습니다. 링크 발급 전에는 선택한 모드에 따라 뷰어(VIEWER)는 5크레딧, 에디터(EDITOR)는 10크레딧을 사용할 수 있는지 확인하며, 후불 사용에 동의한 계정은 허용 한도 내 초과 사용량을 포함합니다. 사용할 수 있는 크레딧이 부족하면 HTTP 402 / 4020 INSUFFICIENT_CREDIT를 반환합니다.

요청​

multipart 요청의 경계 문자열은 HTTP 클라이언트가 생성하도록 두세요. 경계 문자열 없이 Content-Type만 직접 지정하면 요청을 해석할 수 없습니다.

curl --fail-with-body \
-X POST https://api.thinkfree.com/api/office/v1/client-sessions \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
-F "file=@./sample.docx" \
-F 'request={"clientType":"BROWSER","mode":"EDITOR","fileDisplayName":"customer-proposal.docx","userId":"user-1042","docId":"upload-2026-0081","userDisplayName":"Alex Kim","userEmail":"alex@example.com","userAvatarUrl":"https://example.com/profiles/alex.png","language":"en_US","skin":"default"};type=application/json'
필드위치타입필수의미/허용값
Authorization헤더문자열예Bearer {API_KEY}
Content-Type헤더문자열예multipart/form-data; boundary=.... HTTP 클라이언트가 경계 문자열 생성
X-Request-ID헤더문자열아니요 - 기본값: 서버 생성 UUID요청을 추적할 ID, 최대 64자
requestmultipartJSON 객체필수세션 설정. Content-Type은 application/json. storageId와 documentPath는 포함하지 않음
clientTyperequest JSON문자열 enum필수BROWSER
moderequest JSON문자열 enum필수 - 기본값 없음VIEWER는 읽기 전용, EDITOR는 편집·저장
filemultipart바이너리필수비어 있지 않은 Office 파일, 최대 100 MB(104,857,600바이트, 100 MiB). 확장자에 맞는 OOXML/ODF ZIP 또는 legacy OLE 파일 헤더 필요
fileDisplayNamerequest JSON문자열선택 - 기본값: multipart 파일의 파일 이름Office에 표시할 이름, 최대 255자. 확장자로 문서 앱을 선택함. /, \와 제어 문자 또는 이름 전체가 .·..인 값은 허용하지 않음
userIdrequest JSON문자열선택 - 생략하면 세션마다 별도 익명 사용자로 식별1~128자. Unicode 문자·숫자, 공백과 ._@+()- 허용. 같은 사용자에게는 같은 값, 다른 사용자에게는 다른 값 사용. 프로필 변경과 독립적
userDisplayNamerequest JSON문자열선택 - 기본값: 생략표시 이름, 최대 256자. 사용자 식별자로 사용하지 않음
userEmailrequest JSON문자열선택 - 기본값: 생략프로필 이메일, 최대 254자. 인증에 사용하지 않음
userAvatarUrlrequest JSONHTTPS URL 문자열선택 - 기본값: 생략인증 없이 누구나 읽을 수 있는 공개 HTTPS 이미지 주소. 최대 2,048자이며 URL의 인증정보와 fragment는 허용하지 않음. Beta: Office가 아직 이 이미지를 사용자 프로필 아이콘으로 표시하지 않습니다.
docIdrequest JSON문자열선택 - 기본값: 새 세션마다 생성1~48자. ASCII 영문·숫자·_·- 허용. 같은 문서에는 같은 값, 다른 문서에는 다른 값 사용
languagerequest JSON문자열선택 - 입력하지 않으면 Office 요청에서 생략각각 2~8자인 ASCII 영문 두 묶음을 _로 연결. 예: en_US, ko_KR. 생략 시 Office의 언어 설정 사용
skinrequest JSON문자열선택 - 입력하지 않으면 Office 요청에서 생략1~32자인 ASCII 영문·숫자·_·-. 생략 시 Office의 스킨 설정 사용

예제는 사용자에게 user-1042, 이번에 업로드한 사본에 upload-2026-0081을 배정합니다. 같은 사용자에게는 사용자 ID를 유지하고, 별도로 업로드한 사본에는 다른 문서 ID를 배정하세요. 파일 이름으로 문서 식별자가 정해지지는 않습니다. 사용자·문서·세션 ID를 참고하세요.

업로드한 파일은 Upload & Edit 세션의 임시 문서로 보관합니다. 지원 확장자는 doc, docx, odt, xls, xlsx, ods, ppt, pptx, odp입니다. 확장자에 맞는 ZIP 또는 OLE 파일 헤더가 없으면 파일을 저장하기 전에 요청을 거절합니다. 확장자만 바꾼 파일은 사용할 수 없습니다. Office는 문서를 열 때 전체 문서 구조를 검사합니다.

응답​

HTTP 201 Created는 세션을 만들었다는 뜻이며 Office에서 문서 열기에 성공했다는 뜻은 아닙니다. 생성한 세션은 응답 본문의 data.clientSessionId와 data.api.statusUrl로 식별하며, 이 endpoint는 Location 헤더를 반환하지 않습니다. 응답은 스토리지 문서의 세션과 같은 형식을 사용합니다. 두 방식 모두 api.downloadUrl을 반환합니다.

{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": {
"clientSessionId": "9169250d-5328-4d45-844b-9a37cb52f7ac",
"clientType": "BROWSER",
"documentSourceType": "UPLOAD",
"documentLifecycleId": "0d102ee8-cbdd-4667-a5cf-f2e3a1007927",
"mode": "EDITOR",
"status": "CREATED",
"creditsCharged": 0,
"createdAt": "2026-08-10T10:00:00Z",
"browser": {
"openUrl": "https://office.developers.thinkfree.com/cloud-office/api/open-document?ticket=<ticket>",
"openUrlExpiresAt": "2026-08-10T10:05:00Z"
},
"api": {
"statusUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac",
"saveUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/save",
"downloadUrl": "https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/download"
}
}
}
필드타입필수의미/허용값
data.clientSessionIdUUID 문자열필수생성한 클라이언트 세션의 ID. 상태 조회·저장·다운로드 요청에 사용
data.clientType문자열 enum필수항상 BROWSER
data.documentSourceType문자열 enum예UPLOAD; Upload & Edit 흐름으로 Cloud Office에 전달된 문서입니다. 문서 열기 방식은 요청의 mode로 선택합니다.
data.documentLifecycleIdUUID 문자열필수문서의 열기·저장·종료 이벤트 기록을 구분하는 ID. clientSessionId와 별도 값
data.mode문자열 enum필수요청에서 선택한 VIEWER 또는 EDITOR
data.browser객체BROWSER 응답에 필수브라우저에서 Office를 열 때 사용할 정보
data.browser.openUrlHTTPS URL 문자열필수선택한 모드로 문서를 여는 일회용 URL
data.browser.openUrlExpiresAtISO 8601 UTC 문자열필수발급 후 5분인 최초 열기 마감 시각. 이미 열린 문서나 API 사용 기한과는 별개
data.api객체필수세션을 만든 API 키로 호출할 주소 묶음
data.api.statusUrlHTTPS URL 문자열필수Office가 보고한 문서 상태를 조회할 주소. 세션을 만든 API 키 필요
data.api.saveUrlHTTPS URL 문자열EDITOR일 때만 필수, VIEWER는 생략문서 저장 요청 주소. Editor로 열기에 성공한 뒤 고객 서비스의 백엔드에서 호출
data.api.downloadUrlHTTPS URL 문자열필수문서 다운로드 요청 주소. 열기 성공 후 종료 전까지 호출
data.status문자열 enum필수초기값 CREATED. 이후 상태는 api.statusUrl로 조회
data.creditsCharged정수필수세션 생성 요청에서 차감한 크레딧. 문서 열기 성공 시 과금하므로 생성 응답은 0
data.createdAtISO 8601 UTC 문자열필수클라이언트 세션을 만든 시각

Office는 업로드 요청에 지정한 문서와 사용자 정보를 사용합니다. 이 정보는 응답에 다시 포함되지 않습니다.

Upload & Edit는 다른 스토리지 연결에 Save As하는 기능을 지원하지 않습니다. Office가 고객 서비스의 스토리지에 변경 내용을 저장해야 한다면 Bring Your Own Storage를 사용하세요.

임시 업로드 파일은 장기 보관용이 아닙니다. 문서를 닫기 전에 다운로드하세요. 오류 코드는 4001 INVALID_DOCUMENT_REQUEST, 4010 INVALID_API_KEY, 4150 UNSUPPORTED_MEDIA_TYPE, 5021 STORAGE_UNAVAILABLE, 5022 OFFICE_OPEN_URL_UNAVAILABLE입니다. 요청 전체나 JSON part의 Content-Type을 지원하지 않으면 HTTP 415 / 4150을 반환합니다. part가 없거나 JSON이 잘못되면 HTTP 400 / 4001 INVALID_DOCUMENT_REQUEST를 반환합니다. 크레딧 부족은 HTTP 402 / 4020 INSUFFICIENT_CREDIT, 구독 상태 제한은 HTTP 402 / 4021 SUBSCRIPTION_ACCESS_UNAVAILABLE입니다.

브라우저 클라이언트 세션 상태 읽기​

API 역할​

GET /api/office/v1/client-sessions/{clientSessionId}는 Office가 마지막으로 보고한 문서 상태와 이벤트 요약을 반환합니다. 세션 생성에 사용한 동일한 활성 API 키가 필요하며, Office나 브라우저의 실시간 상태를 직접 조회하지는 않습니다.

Developers가 종료 성공 이벤트를 받으면 이벤트의 종료 시각부터 1시간 동안 상태를 조회할 수 있습니다. 종료를 받지 못하면 첫 열기 성공 시각부터 12시간, 열기 성공도 받지 못하면 세션 생성 시각부터 12시간 동안 조회할 수 있습니다. 마감 시각부터는 HTTP 410/4101을 반환합니다. 늦게 도착한 종료 이벤트는 조회 기한을 바꿀 수 있습니다. 기한은 이벤트 수신 시각이 아니라 이벤트가 발생한 시각을 기준으로 계산합니다.

상태는 전달받은 이벤트를 기준으로 확인하세요

CREATED는 열기 성공을 아직 기록하지 않은 상태입니다. OPEN은 열기 이후 종료를 기록하지 않은 상태이며, 브라우저가 여전히 연결되어 있다는 보장은 아닙니다. CLOSED는 종료를 기록했다는 뜻이며, 모든 편집 내용을 저장했다는 뜻은 아닙니다. lastSavedAt과 lastFailure를 함께 확인하고, 반복 조회 간격과 전체 대기 시간을 제한하세요.

요청​

curl --fail-with-body \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
"https://api.thinkfree.com/api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac"
필드위치타입필수의미/허용값
Authorization헤더문자열예브라우저 클라이언트 세션을 생성하는 데 사용된 정확한 Bearer {API_KEY}
clientSessionId경로UUID 문자열예JSON 또는 multipart로 세션을 생성한 응답의 값
X-Request-ID헤더문자열아니요 - 기본값: 서버 생성 UUID요청을 추적할 ID, 최대 64자

응답​

아래 종료된 세션 예제에는 모든 선택 필드가 포함됩니다. 이전 저장 실패는 lastFailure에 남을 수 있으며, 상태 조회 자체가 실패했다는 뜻은 아닙니다.

{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": {
"clientSessionId": "9169250d-5328-4d45-844b-9a37cb52f7ac",
"clientType": "BROWSER",
"documentSourceType": "STORAGE",
"documentLifecycleId": "0d102ee8-cbdd-4667-a5cf-f2e3a1007927",
"status": "CLOSED",
"lastEventAt": "2026-08-08T14:58:00Z",
"documentOpenedAt": "2026-08-08T14:55:09Z",
"lastSavedAt": "2026-08-08T14:56:12Z",
"saveCount": 1,
"closedAt": "2026-08-08T14:58:00Z",
"lastFailure": {
"eventType": "SAVE",
"occurredAt": "2026-08-08T14:57:00Z"
},
"createdAt": "2026-08-08T14:55:00Z"
}
}
필드타입필수의미/허용값
data.clientSessionIdUUID 문자열필수생성한 클라이언트 세션의 ID. 상태 조회·저장·다운로드 요청에 사용
data.clientType문자열 enum필수항상 BROWSER
data.documentSourceType문자열 enum예원본 문서의 유입 경로인 STORAGE 또는 UPLOAD
data.documentLifecycleIdUUID 문자열필수문서의 열기·저장·종료 이벤트 기록을 구분하는 ID. clientSessionId와 별도 값
data.status문자열 enum필수CREATED, OPEN, FAILED, CLOSED
data.lastEventAtISO 8601 UTC 문자열선택 - 첫 이벤트 전에는 생략Office가 보고한 이벤트 중 가장 최근 발생 시각
data.documentOpenedAtISO 8601 UTC 문자열선택 - 열기 성공 기록 전에는 생략Office가 보고한 최초 열기 성공 시각. 12시간 기한의 기준
data.lastSavedAtISO 8601 UTC 문자열선택 - 저장 성공 기록 전에는 생략Office가 보고한 가장 최근 저장 성공 시각. 스토리지·업로드 문서에 모두 적용
data.saveCount정수필수Office가 보고한 저장 성공 이벤트 수. 초기값은 0
data.closedAtISO 8601 UTC 문자열선택 - 종료 성공 기록 전에는 생략Office가 보고한 최초 종료 성공 시각. 저장 완료를 뜻하지 않음
data.lastFailure객체선택 - 실패 기록이 없으면 생략Office가 보고한 가장 최근 실패 이벤트
data.lastFailure.eventType문자열 enumlastFailure가 있으면 필수OPEN, SAVE, SAVE_AS, AUTO_SAVE, LOCK, UNLOCK, CLOSE, CLOSE_AFTER_SAVE, DOWNLOAD, DOWNLOAD_PDF, PRINT
data.lastFailure.occurredAtISO 8601 UTC 문자열lastFailure가 있으면 필수Office가 보고한 실패 발생 시각
data.createdAtISO 8601 UTC 문자열필수클라이언트 세션을 만든 시각

FAILED는 문서 열기에 실패했다는 뜻입니다. 저장 실패는 lastFailure에 기록하며, 열린 Editor의 상태를 FAILED로 바꾸지는 않습니다. 이 상태 조회 응답이 저장을 재시도하거나 문서를 종료하지는 않습니다. 원하는 이벤트를 확인하거나 대기 시간이 끝나면 반복 조회를 멈추세요. 오류 코드는 4001 INVALID_DOCUMENT_REQUEST, 4010 INVALID_API_KEY, 4043 CLIENT_SESSION_NOT_FOUND, 4101 CLIENT_SESSION_EXPIRED입니다.

lastFailure에는 Office가 보고한 실패 이벤트가 기록됩니다. 허용된 이벤트 이름이 모두 나열되어 있어도 모든 Office 버전에서 각 이벤트를 보고한다는 뜻은 아닙니다.

문서 저장​

POST /api/office/v1/client-sessions/{clientSessionId}/save

Office의 현재 문서를 원래 스토리지에 저장하도록 요청합니다. 스토리지 문서는 연결된 스토리지에, 업로드 문서는 임시 저장소에 기록하는 방식입니다. 사용자 PC의 원본 파일을 덮어쓰는 기능은 아닙니다.

저장 결과 확인

Office가 저장 완료를 확인한 경우에만 성공 응답을 반환합니다. 결과를 확인하지 못한 경우에는 저장이 실패했다고 단정하지 말고 문서와 상태를 확인하세요.

요청​

POST /api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/save
Authorization: Bearer tfoak-replace-with-your-key
X-Request-ID: save-example-001
필드위치타입필수의미
Authorization헤더문자열예세션을 생성한 동일한 API 키
clientSessionId경로UUID예저장할 세션
X-Request-ID헤더문자열아니요, 기본값은 서버 생성 UUID최대 64자의 요청 구분값. 중복 저장을 방지하는 값은 아닙니다.

요청 본문과 query는 없습니다. Editor로 연 문서에서만 저장할 수 있습니다. Developers가 열기 성공을 확인한 뒤부터 첫 열기 시각 + 12시간 전에 요청해야 합니다. 종료 성공을 확인하면 남은 시간과 관계없이 저장을 거절합니다.

세션을 만든 API 키와 스토리지가 활성 상태여야 합니다. 저장과 다운로드 모두 아래 접근 조건을 적용합니다. 저장 API는 Viewer 문서에 HTTP 403 / 4031 DOCUMENT_SAVE_NOT_ALLOWED를 반환합니다. 공통 오류는 4001, 4010, 4041, 4042, 4043, 4094, 4101, 4102, 5023, 5031, 5041입니다. 의미는 결과 코드 카탈로그에서 확인하세요.

성공 응답​

Office가 저장 완료를 확인하면 HTTP 200과 다음 JSON을 반환합니다.

{
"success": true,
"code": 0,
"codeDescription": "SUCCESS",
"data": {
"clientSessionId": "9169250d-5328-4d45-844b-9a37cb52f7ac",
"documentLifecycleId": "0d102ee8-cbdd-4667-a5cf-f2e3a1007927",
"saved": true
}
}
필드타입필수의미
data.clientSessionIdUUID 문자열필수생성한 클라이언트 세션의 ID. 상태 조회·저장·다운로드 요청에 사용
data.documentLifecycleIdUUID 문자열성공 시 필수저장 대상 문서의 이벤트 기록 ID
data.savedboolean성공 시 필수Office가 저장을 확인했을 때 true

상태 API의 lastSavedAt·saveCount는 별도로 전달받은 저장 이벤트로 갱신됩니다. 저장 응답만으로 이벤트를 만들지 않습니다. HTTP 504/5041은 저장 결과를 확인하지 못했다는 뜻이며, 저장 실패를 확정하는 응답이 아닙니다. 같은 저장을 즉시 반복하기 전에 문서와 상태를 확인하세요.

현재 문서 다운로드​

GET /api/office/v1/client-sessions/{clientSessionId}/download

Office 서버에 반영된 현재 문서를 파일로 반환합니다. STORAGE와 UPLOAD, Viewer와 Editor 모두 같은 경로를 사용합니다. 다운로드는 원래 저장소의 파일을 덮어쓰지 않습니다. 브라우저에서 아직 Office 서버로 보내지 않은 편집 내용까지 포함한다고 보장하지 않습니다.

원본 스토리지의 예전 파일을 대신 반환하지 않습니다.

요청​

GET /api/office/v1/client-sessions/9169250d-5328-4d45-844b-9a37cb52f7ac/download
Authorization: Bearer tfoak-replace-with-your-key
필드위치타입필수 여부 / 생략 시 동작의미
Authorization헤더문자열필수. 없거나 사용할 수 없는 키이면 4010세션을 만든 API 키
clientSessionIdpathUUID 문자열필수. UUID 형식이 아니면 4001다운로드할 문서의 세션
X-Request-ID헤더문자열선택. 없거나 공백뿐이거나 64자를 넘으면 서버 생성이번 다운로드 요청의 추적 값

요청 본문과 query는 없습니다. 세션을 만든 API 키와 스토리지가 활성 상태여야 합니다.

저장·다운로드 접근 조건​

Developers는 세션을 만든 API 키를 인증한 뒤 종료 기록, 사용 기한, 열기 성공 기록 순으로 확인합니다. 열기 성공 기록이 없으면 생성부터 12시간을 사용 기한으로 적용합니다. 저장과 다운로드 모두 같은 조건을 확인합니다.

요청 시점결과
열기 성공 기록이 없고 생성부터 12시간 미만HTTP 409 / 4094 DOCUMENT_NOT_OPEN
열기·종료 성공 기록이 없고 생성부터 12시간 이상HTTP 410 / 4101 CLIENT_SESSION_EXPIRED
열기 성공 후, 종료 전, 첫 열기부터 12시간 미만Office에 작업을 요청합니다. Office 연결이 종료되었거나 이용할 수 없으면 오류를 반환합니다.
종료 성공을 받은 뒤HTTP 410 / 4102 DOCUMENT_CLOSED
종료를 받지 못했지만 첫 열기부터 12시간 이상HTTP 410 / 4101 CLIENT_SESSION_EXPIRED

성공 응답​

성공 응답은 파일 본문과 다음 헤더로 구성됩니다. 파일 바이트를 문자 인코딩으로 변환하지 않습니다. Developers는 요청을 검사할 때 사용 기한을 확인합니다.

필드타입필수의미
본문바이너리예Office가 반환한 현재 문서 파일
Content-Type헤더 문자열예application/octet-stream
Content-Disposition헤더 문자열예UTF-8 파일 이름을 포함한 attachment
Content-Length헤더 정수파일 크기를 알 수 있을 때파일 바이트 수. 클라이언트는 이 헤더가 없는 응답도 처리해야 합니다.
Cache-Control헤더 문자열예no-store
X-Thinkfree-Success헤더 문자열예true
X-Thinkfree-Code헤더 문자열예0
X-Thinkfree-Code-Description헤더 문자열예SUCCESS
X-Request-ID헤더 문자열예요청 구분값

Office에서 정상적으로 연 문서는 다운로드에 별도의 파일 크기 제한을 적용하지 않습니다. 위의 세션 사용 조건은 계속 적용됩니다.

파일 전송을 시작하기 전에 확인한 오류는 공통 JSON 오류 형식으로 반환합니다. 전송 도중 오류가 발생하면 연결이 중단되므로 클라이언트는 불완전한 파일을 폐기해야 합니다. HTTP 200과 성공 헤더만으로 전체 파일 수신이 완료됐다고 판단하지 마세요. 다운로드도 저장 API의 공통 오류를 사용하며, 4031은 저장에만 적용됩니다. Office 연결이나 파일을 확인하지 못하면 4042 또는 5023이 반환될 수 있습니다. 5041은 저장 API에만 적용됩니다. 저장·다운로드는 추가 크레딧을 차감하지 않습니다.

파일 응답 예제​

파일 내용은 아래 <document bytes> 표시가 아니라 원시 바이너리입니다. Content-Length에는 실제 바이트 수가 들어갑니다.

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="customer-proposal.docx"; filename*=UTF-8''customer-proposal.docx
Content-Length: <actual byte length>
Cache-Control: no-store
X-Thinkfree-Success: true
X-Thinkfree-Code: 0
X-Thinkfree-Code-Description: SUCCESS
X-Request-ID: download-example-001

<document bytes>

저장한 뒤 다운로드하기​

아래 명령은 이미 Editor로 열린 문서를 대상으로 합니다. YOUR_CLIENT_SESSION_ID와 API 키를 실제 값으로 바꾸세요. 첫 명령의 HTTP 200, success: true, data.saved: true를 확인한 다음 두 번째 명령을 실행합니다. 저장 실패나 응답을 받지 못한 상태를 성공으로 취급하지 마세요.

curl --fail-with-body -X POST \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
https://api.thinkfree.com/api/office/v1/client-sessions/YOUR_CLIENT_SESSION_ID/save
curl --fail \
-H "Authorization: Bearer tfoak-replace-with-your-key" \
--dump-header download-headers.txt \
--output customer-proposal.docx \
https://api.thinkfree.com/api/office/v1/client-sessions/YOUR_CLIENT_SESSION_ID/download

다운로드의 HTTP 상태와 Content-Type, Content-Disposition을 확인하세요. 정상 응답이면 customer-proposal.docx에 파일 바이트가 저장됩니다. 오류 JSON을 Office 파일로 취급하지 마세요. 오류 내용을 확인할 때는 파일 출력 대신 응답 본문을 확인하세요.

결과 코드 카탈로그​

고객 서비스는 숫자 code로 응답을 구분합니다. codeDescription은 각 코드를 나타내는 고정 이름입니다.

HTTP숫자 코드코드 설명의미
200/2010SUCCESS요청이 성공했습니다
4004001INVALID_DOCUMENT_REQUEST필수 값, 형식, 경로, 유형 또는 브라우저 클라이언트 세션 UUID가 유효하지 않습니다.
4014010INVALID_API_KEY키가 누락되었거나, 형식이 잘못되었거나, 알 수 없거나, 만료되었거나 폐기되었습니다.
4024020INSUFFICIENT_CREDIT사용 가능한 크레딧과 허용 후불 사용량이 문서 열기에 필요한 양보다 적습니다.
4024021SUBSCRIPTION_ACCESS_UNAVAILABLE현재 구독 상태에서는 이 작업을 사용할 수 없습니다.
4044041STORAGE_CONNECTION_NOT_FOUND연결이 없거나 비활성 상태이거나 다른 계정이 소유하고 있습니다
4044042DOCUMENT_NOT_FOUNDOffice에서 열린 문서를 찾을 수 없습니다. 저장·다운로드할 문서가 아직 열려 있는지 확인하세요.
4044043CLIENT_SESSION_NOT_FOUND세션이 없거나 요청한 API 키로 생성한 세션이 아닙니다
4104101CLIENT_SESSION_EXPIRED상태 조회 또는 문서 작업에 허용된 시간이 지났습니다.
4154150UNSUPPORTED_MEDIA_TYPE브라우저 클라이언트 세션 생성 요청이 지원하지 않는 Content-Type을 사용합니다.
5005001STORAGE_ADAPTER_LIST_FAILED스토리지 연결 목록을 불러오지 못했습니다.
5025021STORAGE_UNAVAILABLE스토리지 Provider에 연결할 수 없습니다.
5025022OFFICE_OPEN_URL_UNAVAILABLE단기 Office 뷰어 또는 에디터 URL을 만들 수 없습니다.
4034031DOCUMENT_SAVE_NOT_ALLOWEDViewer 세션은 API로 저장할 수 없습니다.
4094094DOCUMENT_NOT_OPEN열기 성공을 아직 받지 못했습니다.
4104102DOCUMENT_CLOSED문서 종료 성공을 받았습니다.
5035031OFFICE_DOCUMENT_OPERATION_UNAVAILABLE저장·다운로드를 일시적으로 사용할 수 없습니다.
5025023OFFICE_DOCUMENT_OPERATION_FAILEDOffice가 저장 실패를 알렸거나 유효한 문서 파일을 반환하지 못했습니다.
5045041DOCUMENT_SAVE_RESULT_UNKNOWN저장 결과를 확인하지 못했습니다. 저장 실패로 단정하지 마세요.

여기에 명시된 API 응답에는 X-Request-ID도 포함됩니다. 지원팀이 요청을 찾을 수 있도록 보관하되 API 키, 스토리지 자격 증명, 에디터 URL 또는 고객 파일은 지원 메시지에 첨부하지 않습니다.

프로덕션 체크리스트​

  1. 서비스와 환경마다 별도로 폐기할 수 있는 API 키를 사용하고 만료일을 지정하세요.
  2. 스토리지 연결을 선택할 때 data[].status=ACTIVE가 필요합니다.
  3. 응답의 data.browser.openUrl을 대상 사용자의 브라우저에만 전달합니다.
  4. API 저장·다운로드는 열기 성공 후 종료 전에 호출합니다. 성공 응답과 실제 파일을 확인하기 전에는 저장·다운로드가 완료되었다고 안내하지 마세요.
  5. 숫자 code로 분기하고 X-Request-ID를 유지하며 자격 증명이나 문서 열기 URL을 기록하지 않습니다.
  6. 연결된 스토리지의 경우 버전 관리를 활성화하고 테스트용 파일을 사용하여 동시 편집, 저장, 시간 초과 및 복구를 테스트합니다.
  7. 상태 응답의 documentOpenedAt, closedAt과 위의 조회 규칙으로 기한을 확인합니다. browser.openUrlExpiresAt과는 별개입니다.

읽기 전용 GET 요청은 일시적인 오류에 대해 제한된 지수 백오프 재시도를 사용할 수 있습니다. 세션 생성 요청은 결과를 확인하지 않고 반복하지 마세요. 요청이 성공할 때마다 별도의 브라우저 클라이언트 세션이 생성됩니다.

X-Request-ID는 요청을 추적하기 위한 값이며, 같은 값으로 재요청해도 중복 세션 생성을 막아 주지는 않습니다.