Skip to main content

Upload a file

This guide covers all supported strategies for uploading documents to the Stonal platform. It details every combination you can use to inform the system where — and how — to place your document during the upload process.


Prerequisites

  • A valid OAuth access token (see Authentication)
  • Your organization code (used in the endpoint path)

1. Upload Strategies & Required Fields

Each strategy maps to a combination of manifest fields. Use the table below to identify which payload suits your scenario. Strategies using templates are now recommended as they provide better flexibility and prepare for future architectural changes.

StrategyRequired Manifest FieldsDescription
1. Asset UID + Documentation Templateasset.uid, documentation.templateRecommended: Let the system infer the documentation instance via template.
2. External Asset ID + Documentation Templateasset.externalIds.{source}, documentation.templateRecommended: Resolve asset via external ID and infer documentation via template.
3. Asset + Documentation Template + Folder TemplateStrategy 1 or 2 + folder.templateRecommended: Target a specific folder type within the template-based documentation.
4. Asset UID + Documentation UIDasset.uid, documentation.uidAttach to a specific asset and its exact documentation instance.
5. External Asset ID + Documentation UIDasset.externalIds.{source}, documentation.uidResolve an asset via external ID, then attach to a given documentation.
6. Folder UIDfolder.uidYou know exactly which folder within documentation to target.
7. Documentation UIDdocumentation.uidAssociate with a documentation instance without folder placement.
8. Disconnected Modedisconnected: trueUpload without any asset or documentation association; link manually later.
9. DocumentClass UIDdocumentClassUse a specific document class to categorize the document.
10. Temporary Modetemporary: trueUpload a temporary document that will be deleted after being processed.

2. Manifest Example Payloads

Include only the fields required for your chosen strategy.

{
"asset": { "uid": "822d8c50-0deb-4dae-8def-c9f9eab7f5be" },
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" }
}
{
"asset": {
"externalIds": { "ERP": "BUILDING_001" }
},
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" }
}
{
"asset": {
"externalIds": { "ERP": "BUILDING_001" }
},
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" },
"folder": { "template": "e8df7c2a-b5bb-41fa-8d1f-bea649e6d93d" }
}

2.4 By Asset UID + Documentation UID

{
"asset": { "uid": "asset-123" },
"documentation": { "uid": "doc-456" }
}

2.5 By External Asset ID + Documentation UID

{
"asset": {
"externalIds": { "ERP": "0018" }
},
"documentation": { "uid": "doc-456" }
}

2.6 By Folder UID

{ "folder": { "uid": "folder-789" } }

2.7 By Documentation UID

{ "documentation": { "uid": "doc-456" } }

2.8 Disconnected Upload

{ "disconnected": true }

2.9 By DocumentClass UID

{ "documentClass": "document-class-ef8df" }

2.10 Temporary Upload

{ "temporary": true }

Before using template-based strategies, discover available templates:

3.1 List Available Templates

curl -H "Authorization: Bearer {accessToken}" \
"https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/templates"

Response:

{
"templates": [
{
"id": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d",
"name": "DOE",
"organizationCode": "STONAL",
"attachmentType": "BUILDING_GROUP"
}
]
}

3.2 Get Template Details with Folders

curl -H "Authorization: Bearer {accessToken}" \
"https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/templates/{templateId}?language=fr-FR"

Response:

{
"template": {
"id": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d",
"name": {"fr-FR": "DOE"},
"organizationCode": "STONAL",
"attachmentType": "BUILDING_GROUP",
"folders": [
{
"id": "e8df7c2a-b5bb-41fa-8d1f-bea649e6d93d",
"name": {"fr-FR": "Documents généraux"},
"parentId": null,
"documentClass": {
"identifier": "documentClassIdentifier",
"code": "DPE"
}
}
]
}
}

4. Single-Request API Call

Send both your manifest and file in one multipart/form-data POST:

curl -X POST \
"https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/files/upload" \
-H "Authorization: Bearer {accessToken}" \
-F 'manifest=@manifest.json;type=application/json' \
-F 'file=@/path/to/your/file.pdf;type=application/pdf'

Replace placeholders with your actual values.


5. Response Format

201 Created with JSON:

{
"documentUid": "...",
"duplicateDocumentIds": ["..."]
}

6. Error Handling

  • 400 Bad Request: Missing/invalid manifest fields
  • 404 Not Found: UID (asset, doc, or folder) not found
  • 409 Conflict: Specified asset & documentation aren't linked
  • 422 Unprocessable Entity: Template not found for asset

Handle these responses gracefully in your integration.


7. Best Practices

  • Prioritize templates: More flexible and future-proof than direct UIDs.
  • Discover templates first: Use the /templates API to explore available options.
  • Use external IDs: More robust for integrations with external systems.
  • Include language parameter: Get localized template and folder names.
  • Minimize disconnected mode: Prevent orphaned files.

For more details, see our API specification.


8. Complete Example

For this manifest example:

📄 manifest.json
{
"asset": {
"externalIds": { "ERP": "BUILDING_001" }
},
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" },
"folder": { "template": "e8df7c2a-b5bb-41fa-8d1f-bea649e6d93d" }
}

We will use the following command to upload the file:

⬆️ Uploading the file
curl \
-X POST /v1/organizations/{organizationCode}/files/upload \
-H "Authorization: Bearer {accessToken}" \
-F 'manifest=@manifest.json' \
-F 'file=@sample.pdf'

8.2 Legacy Approach (Still Supported)

For this manifest example:

📄 manifest.json
{
"asset": { "uid": "822d8c50-0deb-4dae-8def-c9f9eab7f5be" },
"documentation": { "uid":"eadfdc1c-e9f7-4808-a91c-a5c8c94ba486" }
}

We will use the following command to upload the file:

⬆️ Uploading the file
curl \
-X POST /v1/organizations/{organizationCode}/files/upload \
-H "Authorization: Bearer {accessToken}" \
-F 'manifest=@manifest.json' \
-F 'file=@sample.pdf'