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.
Strategy | Required Manifest Fields | Description |
---|---|---|
1. Asset UID + Documentation Template ⭐ | asset.uid , documentation.template | Recommended: Let the system infer the documentation instance via template. |
2. External Asset ID + Documentation Template ⭐ | asset.externalIds.{source} , documentation.template | Recommended: Resolve asset via external ID and infer documentation via template. |
3. Asset + Documentation Template + Folder Template ⭐ | Strategy 1 or 2 + folder.template | Recommended: Target a specific folder type within the template-based documentation. |
4. Asset UID + Documentation UID | asset.uid , documentation.uid | Attach to a specific asset and its exact documentation instance. |
5. External Asset ID + Documentation UID | asset.externalIds.{source} , documentation.uid | Resolve an asset via external ID, then attach to a given documentation. |
6. Folder UID | folder.uid | You know exactly which folder within documentation to target. |
7. Documentation UID | documentation.uid | Associate with a documentation instance without folder placement. |
8. Disconnected Mode | disconnected: true | Upload without any asset or documentation association; link manually later. |
9. DocumentClass UID | documentClass | Use a specific document class to categorize the document. |
10. Temporary Mode | temporary: true | Upload a temporary document that will be deleted after being processed. |
2. Manifest Example Payloads
Include only the fields required for your chosen strategy.
2.1 By Asset UID + Documentation Template ⭐ (Recommended)
{
"asset": { "uid": "822d8c50-0deb-4dae-8def-c9f9eab7f5be" },
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" }
}
2.2 By External Asset ID + Documentation Template ⭐ (Recommended)
{
"asset": {
"externalIds": { "ERP": "BUILDING_001" }
},
"documentation": { "template": "f90ee77d-b6cc-41fa-8d1f-bea649e6d93d" }
}
2.3 By Asset + Documentation Template + Folder Template ⭐ (Recommended)
{
"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 }
3. Template Discovery (Recommended Workflow)
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
8.1 Recommended Approach
For this manifest example:
{
"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:
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:
{
"asset": { "uid": "822d8c50-0deb-4dae-8def-c9f9eab7f5be" },
"documentation": { "uid":"eadfdc1c-e9f7-4808-a91c-a5c8c94ba486" }
}
We will use the following command to upload the file:
curl \
-X POST /v1/organizations/{organizationCode}/files/upload \
-H "Authorization: Bearer {accessToken}" \
-F 'manifest=@manifest.json' \
-F 'file=@sample.pdf'