Skip to content
Main site Contact

Files

This page covers:

  • GET /api/File
  • PUT /api/File
  • DELETE /api/File
  • PUT /api/FileBinary
  • PUT /api/FileBinaryDirect
  • GET /api/FileStatus

Fetch a file record by UID or by full file path.

ItemValue
MethodGET
Path/api/File
AuthUser bearer token
ResponseFileMap JSON
ParameterRequiredFormatNotes
fileUIDOne of fileUID or fileNameGUIDIf both are present, fileUID is used first.
fileNameOne of fileUID or fileNameFull stored file pathExample: Design/chair.step
includeShapeletsNotrue or falseAdds shapelet, page, and image detail where available. Defaults to false.
lgFileNumberNoStringPage/view selector for multi-page files. Defaults to "" (empty string).
includeShapesNotrue or falseInternal/mobile-only detail. Do not use unless directed. Defaults to false.
accountNameNoStringOnly use if VizSeek explicitly tells you to. Defaults to null.
FieldMeaning
UIDFile UID
VizSpaceIDCompany or owner context
FileNameStored file path/name
DisplayNameUser-facing display name
AttributesSaved structured attributes
ExtractedAttributesExtracted attributes, when populated
ThumbNailURLFromIDThumbnail URL
PNGURLFromIDLarge-image URL
PDFUrlPDF viewer URL if applicable
HasThumbnailThumbnail availability flag
IndexingFinishedtrue when indexing is complete
AssemblyParents / AssemblyChildrenAssembly relationships for 3D files
{
"UID": "b5d3674c-488c-41cb-a9f7-58a42cac85dd",
"VizSpaceID": "24395dfe-7917-4976-a198-0fe3aa9a6a06",
"FileName": "Design/example-assembly.step",
"DisplayName": "example-assembly.step",
"Attributes": [
"document_number=AX-1000",
"document_type=Assembly",
"weight(kg)=12.7"
],
"ExtractedAttributes": [
"Volume=123.4",
"SurfaceArea=88.2"
],
"ThumbNailURLFromID": "https://your-server.example.com/.../sm.jpg",
"PNGURLFromID": "https://your-server.example.com/.../lg.png",
"HasThumbnail": true,
"IndexingFinished": true
}
Terminal window
curl -G "https://your-server.example.com/api/File" \
-H "Authorization: Bearer USER_BEARER_TOKEN" \
--data-urlencode "fileUID=b5d3674c-488c-41cb-a9f7-58a42cac85dd" \
--data-urlencode "includeShapelets=true"

Upload a file as either:

  • a search-input file (isSearchInput=true, the default), or
  • a persistent file in the company database (isSearchInput=false)
ItemValue
MethodPUT
Path/api/File
AuthUser bearer token
Content-Typeapplication/json
ResponsePlain file UID string
ParameterRequiredFormatNotes
fileYesURL-encoded stringFor search input, send only the extension such as .png or .stp. For database upload, send the full stored path such as Design/chair.step.
isGZipCompressedNotrue or falseLegacy. Only set this when the bytes are gzipped.
isSearchInputNotrue or falseDefaults to true.
indexAsyncNotrue or falseDefaults to false. Search-input only. When true, the file is queued for indexing and the call returns the fileUID immediately instead of waiting for indexing to complete; poll GET /api/FileStatus until it returns HTTP 200 before searching. Not supported for .zip uploads. See Asynchronous indexing.
attributesNoURL-encoded nested query stringOnly applied when isSearchInput=false.
QRCodeIdNoStringInternal only.
categoryIdNoIntegerRequired only for companies that use file categories.
textOnlyNotrue or falseSkip shape indexing.
attrTemplateNoStringDo not use unless VizSeek instructs you to.
uidNoGUIDIf provided, the upload must be a valid GUID. Existing files with that UID are overwritten.
rmIfDupNotrue or falseLegacy. Accepted for backward compatibility but currently has no effect.
isPriorityNotrue or falseDeprecated / no-op. Accepted for backward compatibility but ignored; upload priority is determined by your company profile.
overwriteFileNotrue, false, or omittedControls duplicate-path behavior for company database uploads.
indexAssemblyComponentsNotrue or falseIndex assembly components too.
callbackParamNoStringIncluded in callback payload when callback settings are configured in the UI.
accountNameNoStringOnly use if VizSeek explicitly tells you to.

The body is a JSON string whose value is the base64-encoded file bytes:

"BASE64_FILE_BYTES"

Do not send raw binary here. Use /api/FileBinary or /api/FileBinaryDirect for raw binary uploads.

  • If isSearchInput=true, the file query value should be an extension, not a path. Use .png, .pdf, .stp, and so on.
  • If isSearchInput=false, the attributes query parameter is decoded and parsed as a nested query string such as Width=10.5&Color=Blue.
  • The current controller only reads attributes when isSearchInput=false.
  • .ifz uploads must preserve the original extension before .ifz, for example gear.stl.ifz, not just .ifz.
  • Uploads under 1024 bytes are rejected with HTTP 400. For PUT /api/File the 1024 is measured against the base64 string length, not the decoded byte count.

By default, a search-input upload (isSearchInput=true) blocks until indexing completes, so the returned fileUID is immediately searchable. For large inputs, indexing can take long enough to exceed client or proxy timeouts.

Set indexAsync=true to make the upload non-blocking. The file is queued for indexing and the fileUID is returned immediately, before indexing has finished:

  1. PUT /api/File?...&isSearchInput=true&indexAsync=true returns a fileUID right away.
  2. Poll GET /api/FileStatus?fileUID=... until it returns HTTP 200 with the index timestamp. HTTP 204 means indexing is still in progress; HTTP 422 means indexing failed and polling should stop. See GET /api/FileStatus for the full status-code contract.
  3. Once indexing has completed, search by that fileUID with GET /api/Search.
  • indexAsync applies only to search-input uploads on PUT /api/File and PUT /api/FileBinary. It has no effect on company-database uploads (isSearchInput=false) and is not available on PUT /api/FileBinaryDirect.
  • .zip search inputs are not supported with indexAsync=true and return HTTP 400. Upload the file without indexAsync, or expand the archive and upload each file individually.
  • Searching by a fileUID before GET /api/FileStatus reports completion yields no matches, because the input has not finished indexing.

Python example: upload a search-input file

Section titled “Python example: upload a search-input file”
import base64
import json
import requests
server = "https://your-server.example.com"
token = "USER_BEARER_TOKEN"
filename = "example-input.dxf"
with open(filename, "rb") as f:
body = json.dumps(base64.b64encode(f.read()).decode("ascii"))
resp = requests.put(
f"{server}/api/File?file=.dxf&isSearchInput=true",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
data=body,
)
resp.raise_for_status()
print(resp.text)

Python example: upload into the company database with attributes

Section titled “Python example: upload into the company database with attributes”
import base64
import json
import requests
import urllib.parse
server = "https://your-server.example.com"
token = "USER_BEARER_TOKEN"
filename = "example-assembly.step"
with open(filename, "rb") as f:
body = json.dumps(base64.b64encode(f.read()).decode("ascii"))
attributes_raw = (
"document_number=AX-1000"
"&document_type=Assembly"
"&material=Stainless Steel"
"&weight(kg)=12.7"
)
attributes_qs = urllib.parse.quote(attributes_raw, safe="")
resp = requests.put(
f"{server}/api/File?file=Design/example-assembly.step"
f"&isSearchInput=false"
f"&attributes={attributes_qs}",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
data=body,
)
resp.raise_for_status()
print(resp.text)
PUT /api/File?file=.stp&isSearchInput=true HTTP/1.1
Host: your-server.example.com
Authorization: Bearer USER_BEARER_TOKEN
Content-Type: application/json
"BASE64_FILE_BYTES"

Delete a file by UID.

ItemValue
MethodDELETE
Path/api/File
AuthUser bearer token
ResponseDetermined by HTTP status code; see below
ParameterRequiredNotes
fileUIDYesUID of the file to delete
accountNameNoOnly use if VizSeek explicitly tells you to.

The outcome is communicated through the HTTP status code. Branch on the status code; treat the body as supplementary detail.

StatusBodyMeaning
200 OKtrueThe file was deleted.
404 Not FoundProblem details (JSON)Unknown fileUID for your account — never uploaded, or already deleted. Nothing was deleted.
403 ForbiddenfalseThe file exists, but the token’s user may not delete it. Non-admin users can only delete search inputs they uploaded themselves; company database files require an admin token.
400 Bad RequestProblem details (JSON) or error textThe fileUID parameter is missing, or the request/token is invalid. Correct the request.
401 UnauthorizedEmptyMissing, expired, or invalid bearer token. Re-authenticate.
500 Internal Server ErrorfalseThe deletion failed unexpectedly. Retry; contact support if it persists.

Deletion is not idempotent at the status-code level: deleting the same fileUID twice returns 200 the first time and 404 the second. If your integration deletes defensively, treat 404 as “already gone” rather than as an error.

Terminal window
curl -X DELETE "https://your-server.example.com/api/File?fileUID=b5d3674c-488c-41cb-a9f7-58a42cac85dd" \
-H "Authorization: Bearer USER_BEARER_TOKEN"

Same logical behavior as PUT /api/File, but the body is raw binary instead of a JSON base64 string.

ItemValue
MethodPUT
Path/api/FileBinary
AuthUser bearer token
Content-Typeapplication/octet-stream
ResponsePlain file UID string

Use the same query parameters described for PUT /api/File.

with open("example-input.dxf", "rb") as f:
resp = requests.put(
f"{server}/api/FileBinary?file=.dxf&isSearchInput=true",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/octet-stream",
},
data=f.read(),
)
resp.raise_for_status()
print(resp.text)

Same raw-binary upload pattern as FileBinary, but the response is a populated FileMap object instead of only the UID.

ItemValue
MethodPUT
Path/api/FileBinaryDirect
AuthUser bearer token
Content-Typeapplication/octet-stream
ResponseFileMap JSON
ParameterRequiredNotes
includeShapeletsNoInclude shapelet detail in the returned FileMap.
lgFileNumberNoPage/view selector for multi-page assets.
includeShapesNoInternal/mobile-only detail.
with open("example-input.dxf", "rb") as f:
resp = requests.put(
f"{server}/api/FileBinaryDirect?file=.dxf&isSearchInput=true&includeShapelets=true",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/octet-stream",
},
data=f.read(),
)
resp.raise_for_status()
print(resp.json())

Poll the indexing state of an uploaded file. This is the completion signal for asynchronous uploads: after PUT /api/File or PUT /api/FileBinary with indexAsync=true, poll this endpoint until it returns HTTP 200 before searching by the fileUID.

ItemValue
MethodGET
Path/api/FileStatus
AuthUser bearer token
ResponseDetermined by HTTP status code; see below
ParameterRequiredNotes
fileUIDYesFile UID to poll

The indexing state is communicated through the HTTP status code. Branch on the status code; treat the body as supplementary detail.

StatusBodyMeaning
200 OKIndex timestamp (ISO 8601)Indexing completed — the file can be searched.
204 No ContentEmptyIndexing has not finished yet — keep polling.
422 Unprocessable EntityfailedIndexing failed — stop polling. Verify the file is valid and re-upload; contact support if the failure persists.
404 Not FoundProblem details (JSON)Unknown fileUID — never uploaded, or the file has been deleted. Stop polling and verify the fileUID.
400 Bad RequestProblem details (JSON)The fileUID parameter is missing. Correct the request.
401 UnauthorizedEmptyMissing, expired, or invalid bearer token. Re-authenticate.

204 is the only “try again” signal. 422 and 404 are terminal: further polling will not change the outcome.

  • Responses are served with Cache-Control: no-store. Ensure your HTTP client and any intermediaries honor it — a cached “in progress” response can mask completion indefinitely.
  • Poll at a modest interval (2–5 seconds is typical) and apply an overall timeout appropriate to your file sizes.
Terminal window
curl -G "https://your-server.example.com/api/FileStatus" \
-H "Authorization: Bearer USER_BEARER_TOKEN" \
--data-urlencode "fileUID=b5d3674c-488c-41cb-a9f7-58a42cac85dd"
import time
import requests
def wait_until_indexed(server, token, file_uid, timeout_seconds=600, poll_interval=3):
deadline = time.monotonic() + timeout_seconds
while time.monotonic() < deadline:
resp = requests.get(
f"{server}/api/FileStatus",
headers={"Authorization": f"Bearer {token}"},
params={"fileUID": file_uid},
timeout=30,
)
if resp.status_code == 200:
return resp.text.strip().strip('"') # indexing complete
if resp.status_code == 204:
time.sleep(poll_interval) # still indexing
continue
if resp.status_code == 422:
raise RuntimeError(f"Indexing failed for {file_uid}")
if resp.status_code == 404:
raise LookupError(f"Unknown fileUID: {file_uid}")
resp.raise_for_status() # 400 / 401 / unexpected
raise TimeoutError(f"Indexing did not complete within {timeout_seconds}s")