/api/file/... path has been deprecated and removed.
The supported programmatic workflow is a hybrid REST + S3 + GraphQL flow.
It is the same flow used by the Speckle web app and connectors.
This section documents the entire mechanism so developers do not have to reverse engineer the server.
Pre-requisites
- A personal access token with the
streams:writescope - A Speckle project, where you have a
Can editrole
Get your personal access token from: Avatar → Profile → Personal Access Tokens in the Speckle web app.
Authorization:
This guide requires a Speckle server with the new file import enabled. This is available by default on app.speckle.systems. For self-hosted instances, ensure the
FF_NEXT_GEN_FILE_IMPORTER_ENABLED feature flag is enabled.Overview
Uploading a file and triggering Speckle’s automatic import pipeline is a multi-step process:-
Ask Speckle Server for a presigned upload URL
(GraphQL mutation:
fileUploadMutations.generateUploadUrl) - Upload the file directly to S3 (simple HTTP PUT to the presigned URL)
-
Create a model (if needed)
(GraphQL mutation:
modelMutations.create- optional if you already have a model) -
Tell Speckle to parse and import the file
(GraphQL mutation:
fileUploadMutations.startFileImport) - Check the import status (GraphQL query to monitor the import progress)
- Large files are never sent through the Speckle Server REST endpoints.
- The upload URL points to your server’s configured S3 or S3 compatible storage.
- The ETag returned from S3 is required for step 4 (file import).
- Import results appear as a new Model Version.
Step 1: Generate an upload URL
POST/graphql
Mutation:
fileId from the response - you must use this exact value in Step 4 when triggering the file import. Do not use the filename; use the fileId returned here.
Step 2: Upload the file to the presigned URL
PUT{presignedURL}
Headers required:
- S3 returns an ETag header.
- The ETag is required for the final step.
- The ETag needs to be a double-quoted string. Make sure to escape the quote marks if needed when passing it to the GraphQL mutation.
200 status code, the response headers will contain an ETag header. Record this value:
"\"ad13b92e173...\"").
Step 3: Create a model (if needed)
This step requires a target model, where the file data should be imported to. If you don’t have a model yet, you can create one programmatically: POST/graphql
Mutation:
model.id as it will be used as modelId in the next step.
Step 4: Trigger the file import
Once the file is uploaded, tell Speckle to parse, convert, index and create a new model version. POST/graphql
Mutation:
fileId must be the exact value returned from Step 1’s generateUploadUrl response. Do not use the filename - use the fileId from that response.
Response example:
convertedStatus enum signals the job status where 0=queued, 1=processing, 2=success, 3=error.
Your file is now in the import pipeline. Once parsed, a new Version will appear under the referenced Model.
Step 5: Getting the import status
Once the import has been started, the file import job gets an id atfileUploadMutations.startFileImport.id. This id can be used to get the status of the file import job.
POST /graphql
Query:
convertedStatus enum signals the job status:
0= queued1= processing2= success3= error
convertedMessage.
What developers need to know
File formats supported
File formats supported
For app.speckle.systems: IFC, DWG, DXF, OBJ, STL, 3DM, and others depending on server version.For self-hosted servers: IFC, STL, and OBJ only.
Why are different formats supported in self-hosted vs cloud?
Why are different formats supported in self-hosted vs cloud?
Self-hosted servers use open-source code dependencies, which limits the file formats that can be supported. Formats like DWG, DXF, and 3DM require proprietary libraries that are not available in open-source distributions, so they are only available on app.speckle.systems.
Why is this not REST?
Why is this not REST?
Because:
- Files should go direct to blob storage for performance and scale.
- Restoration of legacy multipart REST endpoints would break S3-first ingestion.
- GraphQL mutations model “actions” better than REST for asynchronous workflows.
Should I ever use the old REST upload?
Should I ever use the old REST upload?
For app.speckle.systems, no. The old REST upload is gone for v3 and beyond.For self-hosted instances, the old REST upload may still be necessary if:
- Your server does not have a publicly available S3 service configured
- The feature flag
FF_LARGE_FILE_IMPORTS_ENABLEDis not enabled