Getting started
Overview What is DWS Viewer API? Dashboard Language support Deployment options Security PrivacyIntegration
Overview Use with your backend Open document in Web SDK PricingClient authentication
Authentication flow Generate a session tokenAPI
Overview Authentication Upload documents API referenceExamples
Node.js integration example Build secure PDF viewers with table extraction Support About NutrientUpload documents
Documents must be uploaded to Nutrient Document Web Services (DWS) before they can be used via server API or and opened in Nutrient Web SDK. Use the POST /viewer/documents endpoint to upload documents.
File upload considerations
Supported file formats — .pdf, .doc, .docx, .ppt, .pptx, .xls, .xlsx, and other formats. For more information, refer to the File type support guide.
Document upload workflow
The typical workflow involves uploading your document and extracting the document ID from the response as demonstrated in the steps below:
Note: This example uses binary file upload, which is the most common and straightforward approach. DWS Viewer API also supports
multipart/form-datafor advanced use cases such as attaching XFDF files or specifying custom metadata.
1. Upload document
Upload your document using binary file upload with headers:
// Server-side document upload.
const uploadDocument = async (fileBuffer, mimeType) => {
const response = await fetch('https://api.nutrient.io/viewer/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': mimeType,
'Content-Length': fileBuffer.length.toString()
},
body: fileBuffer // Binary file data (Buffer, Uint8Array, or ArrayBuffer). NOT FormData.
});
if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}
return await response.json();
};
2. Extract document ID from response
The upload response contains the document ID in a nested structure:
// Handle the nested response structure.
const extractDocumentId = (uploadResponse) => {
// The document ID is always nested in the response data.
return uploadResponse.data?.document_id;
};
// Example response structure:
// {
// "data": {
// "document_id": "actual-document-id-here",
// "title": "document-title"
// }
// }
Troubleshooting
Below are solutions to the most common upload problems:
Document upload errors
"Invalid multipart" (400 Bad Request)
- Cause — Incorrect multipart form data structure
- Solution — Ensure proper FormData usage with correct field names:
// Correct - Using multipart/form-data (convenient for complex uploads)
const formData = new FormData();
formData.append('file', file);
const response = await fetch('https://api.nutrient.io/viewer/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`
// Don't set Content-Type - let browser set it with boundary
},
body: formData
});
// Alternative - Binary upload (simpler for single file uploads)
const response = await fetch('https://api.nutrient.io/viewer/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': file.type,
'Content-Length': file.size.toString()
},
body: fileBuffer
});
"404 Not Found" on document upload
- Cause — Using incorrect API endpoint
- Solution — Ensure you’re using the correct viewer-specific endpoint:
// Incorrect
fetch('https://api.nutrient.io/documents', {...})
// Correct
fetch('https://api.nutrient.io/viewer/documents', {...})
Document ID extraction issues
Document ID is undefined or null
- Cause — Expecting document ID at root level of response
- Solution — Handle the nested response structure:
// Incorrect
const documentId = response.document_id;
// Correct - Handle nested structure
const documentId = response.data?.document_id;
Server implementation considerations
Network timeouts
Set appropriate timeouts for document uploads. For example:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
const response = await fetch(url, {
...options,
signal: controller.signal
});
Error handling
API errors follow the structure below:
{
"error": "error_type",
"message": "Human readable error message",
"details": "Additional error context"
}
Common errors:
-
invalid_document— Document not found or inaccessible -
unsupported_format— File format not supported
Next steps
After uploading a document and obtaining the document ID, you can:
-
Generate a session token for the document1
-
Open the document in Web SDK using the session token2
For a complete server implementation that combines document upload with session token generation, refer to the Node.js integration example guide.