When Paperless API Calls Work in curl, but Fail in n8n
While building an n8n workflow to fetch documents from my Paperless-ngx instance, I followed a typical approach:
- Opened the schema view over at
/api/schema/view/
of my Paperless NGX instance. - Authenticated and explored available endpoints like
/api/documents/
. - After testing one endpoint via the web form, copied the generated curl command.
- Pasted that curl command into an n8n HTTP Request node, thinking it should work the same.
It didn’t.
Then I copied the same curl command into a Linux terminal — and it worked perfectly fine.
The Symptom: Login Page Instead of JSON
I was calling this endpoint:
https://paperless.example.com/api/documents/
But instead of the expected JSON response, the n8n node returned an HTML login page. Even though I included the correct token like this:
Authorization: Token YOUR_TOKEN
The result was something like:
[
{
"form": {
"fields": {
"login": { ... },
"password": { ... }
}
},
"html": "<!DOCTYPE html><html>...<form>Sign in</form></html>"
}
]
Clearly not the /documents/
data I was expecting.
curl Worked Just Fine
Here’s the exact curl command that worked:
curl -X GET 'https://paperless.example.com/api/documents/' \
-H 'Accept: application/json' \
-H 'Authorization: Token YOUR_TOKEN'
That immediately returned the proper JSON document list.
So the credentials were fine. The endpoint was fine. But something about n8n’s request was causing a redirect to the login page.
Why It Happens: Django REST Framework Content Negotiation
Paperless-ngx is built on Django REST Framework (DRF), which tries to “guess” what format you want based on:
- The
Accept
header - The URL (presence of
?format=
) - The
User-Agent
n8n uses Axios under the hood, which sends a verbose Accept header like this:
Accept: application/json,text/html,application/xhtml+xml,...
DRF sees that and thinks:
“Hmm, maybe this is a browser… better send HTML.”
So it serves the login page instead of JSON.
The Fix: Add ?format=json
to the URL
Instead of:
https://paperless.example.com/api/documents/
Use:
https://paperless.example.com/api/documents/?format=json
This explicitly tells DRF to respond with JSON, skipping its content negotiation logic.
Once I made that change in n8n, everything worked instantly — same token, same headers.
Final Working Setup in n8n
In your HTTP Request node:
- Method:
GET
- URL:
https://paperless.example.com/api/documents/?format=json
- Authentication:
None
- Headers:
{
"Authorization": "Token YOUR_TOKEN",
"Accept": "application/json"
}
No special User-Agent needed if ?format=json
is in the URL.
Takeaway
If you’re building a workflow in n8n and your Paperless API request redirects to the login page — even with a valid token — the problem isn’t your credentials.
It’s Django REST Framework making assumptions about your request format.
Just add ?format=json
to the URL to bypass the guesswork and get the response you expect.