Skip to main content

Files API

Operations on a single file. Files and folders share the resource model, the listing endpoint, version history, and locking described in Common conventions; this page covers what applies to files only.

Base URL and scope​

/api/external/v1/files

Read operations need api:read. Upload, delete, rename, move, and copy additionally need api:write.

Download a file for the Intellect viewer​

Intended for Intellect

This endpoint loads the document body when Intellect previews or opens a file, so it checks the VIEW permission, not the DOWNLOAD permission. For an ordinary download, issue a download token and hand it to the browser as described in Download through the browser.

GET /api/external/v1/files/{resourceSeq}/download
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to load
ssintegerNoSharing user 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"

On success the response is the file itself, not the JSON envelope:

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

Download through the browser​

When the download should be performed by the user's browser rather than your server, issue a short-lived token first and hand the returned path to the browser. The token carries the authorization, so the second request needs no API Key.

GET /api/external/v1/files/{resourceSeq}/download-token
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to download
ssintegerNoSharing user seq
Token response
{
"result": true,
"code": 200,
"message": "OK",
"data": {
"linkUrl": "/files/download?dt={token}"
}
}

linkUrl is a relative path. The browser requests it against the domain the user is signed in to, so the second step is not an /api/external/v1 call and carries no Authorization header:

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

The response is the file stream with the same Content-Type, Content-Disposition, and Content-Length headers as above. Calling /api/external/v1/files/download directly instead requires an API Key, which does not fit this browser flow.

To download several resources in one archive, use the multi-resource download described in Common conventions.

Preview a file​

GET /api/external/v1/files/{resourceSeq}/view
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to preview
ssintegerNoSharing user seq

Returns the original file as a stream, not a rendered preview:

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

Upload a file​

Requires api:write
POST /api/external/v1/files

Send the file as multipart/form-data.

ParameterTypeRequiredDescription
filefileYesThe file to upload
pfslongNoParent folder seq; used only when st is duplicate, and the file goes to the root when it is omitted. Required when a shared user uploads
ssintegerNoSharing user seq; null when uploading to your own drive
stenumNoSave type, case-insensitive - duplicate (default) adds a new file with a copy number, version adds a new version of rs, overwrite replaces rs
rslongNoTarget resource seq; required when st is version or overwrite, otherwise the request fails with 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 and overwrite act on the rs file, so pfs is not used with them. Uploading beyond the account quota fails with QUOTA_003.

Rename a file​

Requires api:write
PATCH /api/external/v1/files/{resourceSeq}/rename
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to rename
rnstringYesNew name
ncpenumNoName-collision policy, case-insensitive - NONE (default) rejects a duplicate name with RESOURCE_006, AUTO appends a number
pfslongNoParent folder seq; required with ncp=NONE for a file that is not in the root. The duplicate-name check runs against this folder, and against the root when it is omitted. Not used when ncp is AUTO
ssintegerNoSharing user 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"}'

The response returns the name that was actually applied in data.name, without the extension - an rn of test11.docx returns a name of test11. It differs from rn when AUTO resolved a collision.

Move a file​

Requires api:write
POST /api/external/v1/files/{resourceSeq}/move
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to move
tsintegerNoTarget user seq; required when the caller did not create the share
pfslongNoDestination folder seq; required when the caller did not create the share
ssintegerNoSharing user 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}'

Copy a file​

Requires api:write
POST /api/external/v1/files/{resourceSeq}/copy
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to copy
tsintegerNoUser seq to copy to; null when the caller provides the share
pfslongNoDestination folder seq; required when it differs from the sharing user
ssintegerNoSharing user seq; null when the caller provides the share

The optional Accept-Language header sets the language of the copy's name:

LanguageCopy name
ko{name}의 사본.{ext}
enCopy of {name}.{ext}
esCopia de {name}.{ext}

Returns 201 Created with the new resourceSeq. Copying beyond the account quota fails with QUOTA_003.

Delete a file​

Requires api:write
PATCH /api/external/v1/files/{resourceSeq}/delete
ParameterTypeRequiredDescription
resourceSeqlongYesPath parameter - the file to delete

Only a file you own can be deleted, which is why there is no ss parameter. A file shared with you fails with RESOURCE_005, and a locked file fails with RESOURCE_LOCK_ASPECT_002.

The file moves to the trash rather than being removed. See Users for listing, restoring, and permanently deleting trashed items.

Create a new Office document​

Requires api:write

Creates an empty Word, Spreadsheet, Presentation, or note document from a built-in template, without uploading a file.

POST /api/external/v1/documents
ParameterTypeRequiredDescription
ttenumYesTemplate type - word, excel, ppt, or note
pfslongNoParent folder seq. In your own drive, the document goes to the root when it is omitted. Required when creating in a shared folder (ss is not you); omitting it then fails with PERMISSION_002
ssintegerNoSharing user seq; null when creating in your own drive

The Accept-Language header selects both the template and the file name. Korean (ko), English (en), and Spanish (es) templates are available; any other language fails with FILE_002 because no template exists for it.

LanguageFile names
ko새 문서.docx, 새 프레젠테이션.pptx, 새 스프레드시트.xlsx, 새 노트.tfi
enNew Document.docx and the matching English names for the other types
esNuevo documento.docx and the matching Spanish names for the other types

If the same name already exists in the target folder, a numbered name is used, such as 새 문서 (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 is the owner of the drive the document was created in. When you create in a shared folder, it is the sharing user, not the caller.

The target folder is checked for the UPLOAD permission. Failures use the common failure envelope:

StatuserrorCodeCause
400REQUEST_001Request validation failed
403PERMISSION_001The target folder is not shared with the caller
403PERMISSION_002The caller lacks the UPLOAD permission, or pfs is missing for a shared folder
404RESOURCE_005The target folder does not exist
404FILE_002No template for the requested language
400QUOTA_003Not enough storage capacity
Failure response
{
"result": false,
"code": 404,
"errorCode": "FILE_002",
"message": "{message}"
}

Editor session endpoints​

The web-office endpoints back a browser editing session: the editor reads document metadata, fetches the file, locks it while editing, writes it back, and unlocks it. Use them when you host the Thinkfree editor yourself. For embedding an editor through a supported SDK instead, see 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
The caller chooses the acting user

loginUserSeq is supplied by the caller, not derived from the API Key. The server checks only that the named user belongs to the same tenant as the key - it does not check that the user matches the key's own account. Any key holder can therefore act as any user in that tenant through these endpoints. Treat a key that can reach them as a tenant-wide credential, and do not pass a browser-supplied loginUserSeq through without deciding server-side who the caller is allowed to act as.

These endpoints skip the scope check

All five are exempt from the scope check because they serve the editor session flow. A key holding only api:read can call lock, put, and unlock, which change stored content.

Common parameters​

ParameterTypeRequiredDescription
loginUserSeqlongYesPath parameter - the user the session acts as
docIdstringYesDocument identifier, formed as the resource owner seq and the resource seq joined by a hyphen ({ownerUserSeq}-{resourceSeq}, such as 21-512)
appenumYesEditor surface, such as WORD_EDITOR, CELL_VIEWER, or SHOW_WATCHER; required by info, get, and put
user_idstringYesSigned-in account name; required by info, get, and put
langstringNoSession language, such as ko_KR. Sets the language (ko, en, es) of the permission-denied message and of an anonymous user's display name

The app value names both the application and the mode, giving 15 values. Applications are WORD, CELL, SHOW, HWP, and PDF; modes are EDITOR, VIEWER, and WATCHER.

An *_EDITOR value is checked for the EDIT permission; *_VIEWER and *_WATCHER are checked for the VIEW permission. This applies to info, get, and put, and the check is skipped for the document owner. An anonymous user who arrives through a public link can open only documents shared with PUBLIC_LINK.

Read document metadata​

GET /api/external/v1/web-office/{loginUserSeq}/info
ParameterTypeRequiredDescription
typeenumNoRequest type, case-insensitive - open, download (original file), pdf_download (PDF conversion), or print. download and pdf_download are recorded as downloads in the audit log

Returns an XML document with the root element <property>, not JSON. Permissions are checked when the request is made, and a caller without them gets HTTP 403. The read, write, and locked fields do not reflect the actual permission or lock state.

FieldDescription
typeAlways file
nameFile name, in CDATA
modifiedLast modified time, epoch milliseconds
read, writeAlways true
lockedAlways false
sizeFile size in bytes
fullNameDisplay name of the user
userCursorNameThe user_id sent in the request; for an anonymous user, an anonymous animal name in lang
profileImageProfile image of the user
cursorColorCursor color, random on every request
revisionSame value as modified
currentVersionNumberCurrent version number
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>

A missing resource returns HTTP 200 with the plain-text body NotExist, so check the body as well as the status code.

Fetch the document​

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

Streams the file as application/octet-stream. A *_VIEWER request is recorded in the audit log as a preview; any other app is recorded as opening the document.

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

Store the document​

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

Send the document body as application/octet-stream. The response is the docId as plain text.

ParameterTypeRequiredDescription
app, user_id, docId-YesSee Common parameters
sizelongYesSize of the uploaded document in bytes
typeenumNoSave reason, case-insensitive. save, autoPut, close, a missing value, or any other value saves the body as a new version. saveAs and autoSave save nothing and only return the docId
openTimestamplongNoAccepted but unused

Unlike the other web-office endpoints, a missing or malformed required parameter fails with 400 REQUEST_001 as JSON. Exceeding the storage quota returns 500 Internal Server Error, not QUOTA_003.

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"

Lock and unlock the document​

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

Both take only docId; app, user_id, and lang are not needed. They return 200 OK with no body. If no resource matches docId, they fail with HTTP 400 and a plain-text message.

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"

Editor session errors​

Several of these failures carry no errorCode, or no body at all, so they cannot be matched against Errors. Check both the status code and the body.

CaseResponse
Missing required parameter or invalid app - info, get, lock, unlockHTTP 500, no body
Missing or malformed required parameter - put400 REQUEST_001, JSON
No user matches loginUserSeq404 USER_005, JSON
The user belongs to a different tenant from the API Key403 AccessDenied, plain text
Malformed docId500 Internal Server Error, JSON without errorCode
No permission for the document403, plain-text permission-denied message in lang
Missing resource - info200 NotExist, plain text
Missing resource, file read or save failure, or quota exceeded - get, put500 Internal Server Error, JSON without errorCode
Missing resource - lock, unlock400, plain-text lock or unlock failure message

Errors​

Failures on the files and documents endpoints use the common failure envelope:

Failure response
{
"result": false,
"code": 400,
"errorCode": "QUOTA_003",
"message": "{message}"
}
StatuserrorCodeCause
400RESOURCE_001Delete failed
404RESOURCE_005Resource not found
409RESOURCE_006Duplicate name
400RESOURCE_014rs is missing
423RESOURCE_LOCK_ASPECT_002The resource is locked
400QUOTA_003Not enough storage capacity
500RESPONSE_001Server error

See Errors for the full list of codes. The web-office endpoints are covered in Editor session errors.