How do I correctly to handle file uploads from customers in Web Messaging - accepted MIME types and size limits? The POST /api/v2/analytics/conversations/details/query endpoint returns a 400 Bad Request with {"errorCode": "validation-failed", "message": "Invalid file type"} when sending application/pdf payloads, yet the SDK documentation implies support for standard documents. Is there a strict whitelist in the guest.messaging.upload configuration or a specific Content-Type header requirement I am missing in the fetch call?
TL;DR: Stop using Analytics endpoints for file uploads. Use the Conversation API POST /api/v2/conversations/messaging/{conversationId}/messages with proper MIME headers.
The easiest way to fix this is to switch from the analytics query endpoint to the actual messaging ingestion endpoint. Analytics is read-only. You are hitting a 400 because analytics/conversations/details/query does not accept multipart form data or file payloads.
Use this structure instead:
POST /api/v2/conversations/messaging/{conversationId}/messages
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="doc.pdf"
Content-Type: application/pdf
<binary_pdf_data>
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Ensure your platform client has the conversation:message:write scope. The API validates MIME types against a strict internal whitelist. application/pdf is allowed, but the payload structure must be standard multipart. If you are using the Java SDK, use MessagingConversationMessage with the file field populated, not the analytics builder. This avoids the type mismatch entirely.
The root of the issue is that you’re hitting a read-only analytics endpoint with a write payload. use platformClient.conversations.messagingPostMessage from the js sdk instead. it handles the mime validation and multipart encoding automatically, so your pdfs will actually stick.
You need to be careful with how you handle the file content before sending it to the messaging endpoint. Coming from Five9, I initially tried sending the raw file object, but CXone Studio and the API expect specific formatting. The 400 error often persists even with the correct endpoint if the Content-Type header isn’t explicitly set to multipart/form-data or if the MIME type isn’t strictly validated by your client-side code first.
Make sure you are constructing the FormData object correctly. If you are using the JS SDK, messagingPostMessage helps, but you still need to ensure the file part is named correctly.
let formData = new FormData();
formData.append('file', fileObj, 'document.pdf'); // filename matters for MIME detection
formData.append('message', 'Here is the document');
platformClient.conversations.messagingPostMessage(conversationId, formData);
I hit a similar issue where application/pdf was rejected because the client sent application/octet-stream. Double-check that your frontend preserves the original MIME type when appending to the form data.
Use requests.post with files param. The analytics endpoint is read-only.
import requests
url = f"{base}/api/v2/conversations/messaging/{cid}/messages"
headers = {"Authorization": f"Bearer {token}"}
files = {"file": ("doc.pdf", open("doc.pdf", "rb"), "application/pdf")}
requests.post(url, headers=headers, files=files)
Check your org settings for specific MIME whitelists.