API file upload

Using the example in the docs to upload a file to a document returns a 400 error. The document was created successfully and as GET request to /api/v4/documents/{document_id} returns valid info about the document successfully.


with open(file=‘filename.pdf’, mode=‘rb’) as file_object:
response = requests.post(url=‘’, auth=(‘XXX’,‘XXX’), files={‘file_new’: file_object}, data={‘action’: 1})

{‘Server’: ‘gunicorn’, ‘Date’: ‘Fri, 10 Nov 2023 18:46:45 GMT’, ‘Connection’: ‘close’, ‘Content-Type’: ‘application/json’, ‘Vary’: ‘Accept, origin, Accept-Language, Cookie’, ‘Allow’: ‘GE
T, POST, HEAD, OPTIONS’, ‘X-Frame-Options’: ‘DENY’, ‘Content-Length’: ‘43’, ‘Content-Language’: ‘en’, ‘X-Content-Type-Options’: ‘nosniff’, ‘Referrer-Policy’: ‘same-origin’}

Something missing from the request payload?

The API has changed and you are porbably hit by https://gitlab.com/mayan-edms/mayan-edms/-/issues/1155 which was unfortunately closed due to unlucky user interaction.

I finally used the /documents/upload/ endpoint which ties together the document creation and the file upload in one request.

The reasons are quite clear. It was closed because it was not a bug.

Devs asked the forum for a decision that added a tons of features with the downside of one backward incompatible change. The community spoke and wanted the change.

I admire the patience the devs have with the community. Another reason to trust Mayan, very mature team.

1 Like

Well, please read #1155 carefully to get the correct picture.

The original issue created by me was that the documentation (and still does as of today) at docs/apps/rest_api · master · Mayan EDMS / Mayan EDMS · GitLab and REST API — Mayan EDMS 4.5.8 documentation IMHO displays an invalid example after the API changes (which basically the cited issue created by me was about). Please correct me when I am wrong.

Later another user stepped in providing more or less wrong input, also based on insufficient reading of changelogs. Which led to closing unfortunately the issue on the whole.

Thus the problem described by the original poster of this thread is comprehensible.

Thank you for pointing me in the right direction, got the /documents/{document_id}/files method call working… tried the /documents/upload/ method as it would be convenient, but apparently I’m missing something there also, the request looks like this:

with open(file=‘123.pdf’, mode=‘rb’) as file_object:
response = requests.post(url=‘’, files={‘file_new’: file_object}, data={‘document_type’:{‘label’:‘Drawing’}})

and 404 response when adding a metadata item to a doc:

response = requests.post(url=‘’, data={‘metadata_type’:{‘name’:‘DrawingNo’}, ‘value’:‘000510’}

Appreciate any additional pointers…


Please find the code snippets below from my working API integration. In my case I’m always using ids for foreign objects (Metadata Type or Document Type). I also noticed that my files-object for the first API call looks different. Do you also get a 404 response for the upload call?

def upload_document(self, document_type_id, label, file, description=None, filename=None, language=None):
    url = f'......../documents/upload/'
    files = { 'file':  (f'{filename}', file )}
    data = {
        'document_type_id': document_type_id,
        'description': description or '',
        'label': label,
        'language': language or 'Eng',
    res = requests.post(url, auth=self.auth, verify=False, data=data, files=files)             
    return res.json()


def post_document_metadata(self, doc_id, metadata_type_id, value):
    url = f'........../documents/{doc_id}/metadata/'
    data = {
        'metadata_type_id': metadata_type_id,
        'value': value
    res = requests.post(url, auth=self.auth, verify=False, data=data)             
    return res.json()

Best reagards

1 Like

Thanks; this was very helpful!

I’m wondering if the nested json in my examples was getting mangled when passed via the data parameter? (re: Formatting a nested json for use with Python Requests - Stack Overflow)

Refering to the beginning of this topic, we have two API endpoints for uploading files behaving differently:

### upload a new document ###
POST .../documents/upload/
### upload a new document file ###
POST .../documents/{document_id}/files/

In case of success, the first endpoint returns 200 OK state with the new document as JSON data as content.

While the second endpoint returns 202 Accepted state with an empty content body. Shouln’t it also return the JSON data of the created record (document file)? How can we else get the data of the created record?

I’m using the latest Mayan 4.5.7 version, as of now the included swagger documentation of the post document file endpoint seems to be out of date - parameters and returning values are different than documented.

Open source devs are a special breed of humans. I would not have had the patience to answer this politely after a user completely misses the point and then a tires to gaslight me.