Upload 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.

This example uses binary file upload, which is the most common and straightforward approach. DWS Viewer API also supports multipart/form-data for advanced use cases such as attaching XFDF files or specifying custom metadata.

Uploading the 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();
};

Extracting the document ID from the 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 the 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 the 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 the document ID at the 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:

  1. Generate a session token for the document.
  2. Open the document in Web SDK using the session token.

For a complete server implementation that combines document upload with session token generation, refer to the Node.js integration example guide.