Created
October 6, 2025 13:09
-
-
Save BoxedBrain/d0a135a3d2d40eaf5cbd887febdc1e78 to your computer and use it in GitHub Desktop.
N26 Bank - Download ALL Monthly Statements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| ========================================== | |
| N26 Monthly Statements Auto Downloader (Browser Console) | |
| ========================================== | |
| Description: | |
| Automatically downloads all N26 account statements (PDFs) | |
| starting from a specified month up to the current month. | |
| How it works: | |
| - Fetches URLs in the format: | |
| https://app.n26.com/download-statement/statement-YYYY-MM | |
| - Detects valid PDFs and downloads them automatically. | |
| - Waits between downloads to avoid rate limits. | |
| - If a 429 (Too Many Requests) occurs, waits 1.5 minutes and retries. | |
| Configurable variables: | |
| startYear → first year to download from (e.g.: 2018) | |
| startMonth → first month (e.g.: 8 = August) | |
| delay → pause (ms) between successful downloads (default: 5000 = 5 sec) | |
| retryWait → wait time (ms) after HTTP 429 before retry (default: 90000 = 1.5 min) | |
| Usage: | |
| 1. Log in to your N26 account in the same browser tab. | |
| 2. Open the browser console (F12 → Console). | |
| 3. Paste the full code below and press Enter. | |
| 4. PDFs will be automatically downloaded month by month. | |
| Note: | |
| If fetch fails (e.g., due to CORS), the script will open the statement URL in a new tab and you need to save the PDFs manually. | |
| */ | |
| (async()=>{ | |
| const startYear=2018, startMonth=8, delay=5000, retryWait=90000; | |
| const now=new Date(), endYear=now.getFullYear(), endMonth=now.getMonth()+1; | |
| const sleep=ms=>new Promise(r=>setTimeout(r,ms)); | |
| const pad=n=>String(n).padStart(2,'0'); | |
| const download=(blob,name)=>{ | |
| const a=document.createElement('a'); | |
| a.href=URL.createObjectURL(blob); | |
| a.download=name; | |
| a.click(); | |
| URL.revokeObjectURL(a.href); | |
| }; | |
| for(let y=startYear;y<=endYear;y++){ | |
| const mStart=y===startYear?startMonth:1, mEnd=y===endYear?endMonth:12; | |
| for(let m=mStart;m<=mEnd;m++){ | |
| const url=`https://app.n26.com/download-statement/statement-${y}-${pad(m)}`; | |
| const filename=`statement-${y}-${pad(m)}.pdf`; | |
| console.log(`→ Trying: ${url}`); | |
| let done=false, retries=0; | |
| while(!done){ | |
| try{ | |
| const r=await fetch(url,{credentials:'include'}); | |
| if(r.status===429){ | |
| retries++; | |
| console.warn(`⚠️ 429 Too Many Requests — waiting ${retryWait/1000}s before retry #${retries}`); | |
| await sleep(retryWait); | |
| continue; | |
| } | |
| if(r.ok){ | |
| const t=r.headers.get('content-type')||''; | |
| if(t.includes('pdf')){ | |
| const b=await r.blob(); | |
| download(b,filename); | |
| console.log(`✓ Downloaded: ${filename}`); | |
| }else{ | |
| console.warn(`✗ Not a PDF (content-type: ${t})`); | |
| } | |
| }else{ | |
| console.warn(`✗ HTTP ${r.status} for ${url}`); | |
| } | |
| done=true; | |
| }catch(e){ | |
| console.warn(`⚠️ Error fetching ${url}`,e); | |
| window.open(url,'_blank'); | |
| done=true; | |
| } | |
| } | |
| await sleep(delay); | |
| } | |
| } | |
| console.log('All done.'); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment