Summary
As of early August 2026, Cloudflare in front of www.notion.so rejects api/v3 requests that carry no User-Agent header with a 403 (Cloudflare HTML block page). notion-client's fetch sets only Content-Type, and Node's undici adds no default UA, so every server-side call from Node fails.
This silently breaks any SSR/SSG/CI usage of notion-client — the same code that worked for years starts returning 403 with no library change.
Environment
notion-client 7.10.0 (latest)
- Node 24 (undici fetch), reproduced both locally and on Vercel serverless
Reproduction
Same page ID, same endpoint, same request body — the UA header is the only variable:
| Request |
Result |
notion-client as-is (no User-Agent) |
403, Cloudflare HTML block page (~95ms) |
Same payload + curl/8.7.1 UA |
200 |
| Same payload + browser UA |
200 |
Minimal repro without the library:
// 403:
await fetch('https://www.notion.so/api/v3/loadPageChunk', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ pageId, limit: 100, cursor: { stack: [] }, chunkNumber: 0, verticalColumns: false }),
})
// 200 — identical except for the UA header:
await fetch('https://www.notion.so/api/v3/loadPageChunk', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0 ...' },
body: /* same */,
})
Notion's status page shows no incident — this is bot protection on the unofficial private API, not an outage.
Workaround
ofetchOptions on the constructor merges into every request the client makes, so no library change is needed to unblock:
const notion = new NotionAPI({
ofetchOptions: {
headers: {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
},
},
})
Any non-empty realistic UA works (curl's does too).
Proposed fix
Have notion-client send a default User-Agent (overridable via ofetchOptions) so requests work out of the box again. Happy to send a PR if maintainers agree with the approach.
Possibly related
Summary
As of early August 2026, Cloudflare in front of
www.notion.sorejectsapi/v3requests that carry noUser-Agentheader with a 403 (Cloudflare HTML block page).notion-client's fetch sets onlyContent-Type, and Node'sundiciadds no default UA, so every server-side call from Node fails.This silently breaks any SSR/SSG/CI usage of
notion-client— the same code that worked for years starts returning 403 with no library change.Environment
notion-client7.10.0 (latest)Reproduction
Same page ID, same endpoint, same request body — the UA header is the only variable:
notion-clientas-is (no User-Agent)curl/8.7.1UAMinimal repro without the library:
Notion's status page shows no incident — this is bot protection on the unofficial private API, not an outage.
Workaround
ofetchOptionson the constructor merges into every request the client makes, so no library change is needed to unblock:Any non-empty realistic UA works (curl's does too).
Proposed fix
Have
notion-clientsend a defaultUser-Agent(overridable viaofetchOptions) so requests work out of the box again. Happy to send a PR if maintainers agree with the approach.Possibly related