Good morning, Documateo 👋
Your one-stop command centre. Tick tasks as you complete them. Click Save Progress often. Use Backup before clearing browser cache.
🧭 How to use this dashboard (read this first!)
You're a complete beginner — that's perfectly fine. This dashboard was built to guide you step by step. Here's how it works:
1
Navigate using the left sidebar — each section has a specific focus (Today's tasks, SEO, Monetization, etc.)
2
Click any task item to mark it as done (it turns green with a ✓). Click again to unmark.
3
Click "▼ Show Steps" on any task — this reveals a detailed step-by-step guide written for beginners. Every task has one.
4
Press "💾 Save Progress" after completing tasks. Your progress saves to your browser — it won't disappear unless you clear cache.
5
Use "Backup / Restore" to export your progress as JSON and paste it into a Google Doc or Notion. Do this weekly!
6
Start with "🔥 Do Today" in the sidebar — it shows your most urgent 8 tasks right now.
Big win already done! Cloudflare Pages Function is deployed. Google can now read all 48 tool pages + 90 blog posts. The #1 technical blocker is fixed. Now focus on getting those pages indexed.
Tools Live
48
32 PDF · 14 Image · 2 Video
Blog Posts
90+
Sitemap submitted to GSC
Indexed Pages
34
Update as GSC shows more
Revenue Streams
3
Ads · Affiliate · PRO
🔥 This Week's Priority
✓
Deploy Cloudflare Pages Function
Request indexing for all 102 pages in GSC
Create Privacy Policy + About page
Apply for Google AdSense
Install Microsoft Clarity (free heatmaps)
Resubmit sitemap in Google Search Console
📈 Revenue Forecast
| Month | Est. Visits | Earnings |
|---|---|---|
| Month 1 | 500–2k | ₹300–₹1,100 |
| Month 2 | 2k–6k | ₹1,500–₹5,300 |
| Month 3 | 6k–15k | ₹4,000–₹13,000 |
| Month 4 | 15k–30k | ₹9,500–₹27,000 |
| Month 5 | 30k–60k | ₹21,000–₹51,000 |
| Month 6 | 60k–1.2L | ₹46,000–₹1,23,000 |
Revenue = Ads (50%) + Affiliates (30%) + PRO subs (20%). Grows exponentially as SEO compounds.
📊 Overall Task Progress
0 tasks completed0%
Monetization
SEO & Blog
Tool Roadmap
Security
Legal & Safety
Reachability
🔥 Do Today
Your highest-leverage actions right now. Each task here has a detailed beginner guide — click "▼ Show Steps" to expand it.
The Cloudflare Function is live. Google's crawlers noticed the change. The window for fast indexing is open RIGHT NOW — every day you delay costs you organic traffic. Do these tasks today.
⚡ Right Now — Next 2 Hours
✓
Cloudflare Pages Function deployed ✅
Request indexing: 10 priority pages in GSC URL Inspection
📋 Step-by-Step Guide — Requesting Indexing in Google Search Console
⚠️ What is Google Search Console? It's a free tool by Google where you can see how your website appears in Google search. You should have already set this up when you added your domain. If not, go to search.google.com/search-console first.
- 1Open your browser and go to: search.google.com/search-console — log in with the same Google account you used to set it up.
- 2In the left sidebar, click "URL Inspection". A search bar will appear at the top of the page.
- 3Type or paste your first URL:
https://documateo.com/pdf/merge— then press Enter. Wait about 5-10 seconds for the result to load. - 4You'll see a status message. Look for a button that says "Request Indexing" — click it. Google will put that page in the indexing queue.
- 5Repeat this for the other 9 priority pages (below). You're limited to 10 per day. Google usually indexes them within 24-72 hours.
📌 Today's Priority Order:
1. /pdf/merge → 2. /pdf/compress → 3. /pdf/split → 4. /image/remove-bg → 5. /image/compress → 6. /pdf/pdf-to-word → 7. /image/resize → 8. /pdf/protect → 9. /video/extract-audio → 10. /pdf/rotate
Do 10 today, 10 tomorrow, and continue each day for ~10 days until all 102 pages are requested.
1. /pdf/merge → 2. /pdf/compress → 3. /pdf/split → 4. /image/remove-bg → 5. /image/compress → 6. /pdf/pdf-to-word → 7. /image/resize → 8. /pdf/protect → 9. /video/extract-audio → 10. /pdf/rotate
Do 10 today, 10 tomorrow, and continue each day for ~10 days until all 102 pages are requested.
Resubmit sitemap.xml in Google Search Console
📋 Step-by-Step Guide — Resubmitting Your Sitemap
⚠️ What is a sitemap? It's a file called sitemap.xml that lists all the pages on your website. It helps Google discover your pages faster instead of searching randomly. You should already have one at: documateo.com/sitemap.xml
- 1Go to search.google.com/search-console and log in.
- 2In the left sidebar, scroll down and click "Sitemaps" (under the Indexing section).
- 3You should see your existing sitemap already listed (something like
sitemap.xml). If not, typesitemap.xmlin the "Add a new sitemap" box and click Submit. - 4If your sitemap is already listed, click the 3-dot menu (⋮) next to it → click "Resubmit". This tells Google: "I've made changes, please come and re-read everything."
- 5Google will show "Pending" status — this is normal. It can take 24-72 hours to start crawling.
💡 Do this right after your Cloudflare fix. Since Google now gets different HTML (with real content instead of a blank page), resubmitting tells it to come back and re-read everything.
📅 This Week — Before Friday
Create Privacy Policy page at /privacy-policy
📋 Step-by-Step Guide — Creating a Privacy Policy (Beginner-Friendly)
⚠️ Why do you need this? Google AdSense requires every website that shows ads to have a Privacy Policy page. Without it, you'll be instantly rejected. This explains to users what data you collect (even basic things like cookies). You do NOT need a lawyer — free generators work fine.
- 1Open a new tab and go to: privacypolicygenerator.info — this is a free, trusted tool used by thousands of websites.
- 2Fill in the form: Website Name =
Documateo| Website URL =https://documateo.com| Country =India| State = your state. - 3On the next page, tick these boxes: ✅ Google Analytics ✅ Google AdSense ✅ Log Data ✅ Cookies ✅ Third-party links. Then click "Generate Privacy Policy".
- 4Click "Select All" and copy the entire generated text. This is your privacy policy.
- 5In your website's code (React frontend), create a new page route at
/privacy-policy. Paste the privacy policy text there as a simple text/HTML page. - 6In your website footer, add a link that says "Privacy Policy" pointing to
/privacy-policy. AdSense reviewers specifically look for this footer link. - 7While you're at it, use the same generator to create a Terms of Service page at
/terms-of-service. Same process, different option on the generator.
💡 The #1 reason tool websites get AdSense rejected is missing legal pages. Do this BEFORE applying for AdSense. Takes 20 minutes, pays dividends forever.
Write About page (200+ words, founder story)
📋 Step-by-Step Guide — Writing Your About Page
⚠️ Why does this matter? Google's quality raters are actual humans who look at websites before ranking them. They check: Is this a real website by a real person? Your About page is the answer. AdSense reviewers also look here to verify legitimacy.
- 1Create a new page in your React app at the route
/about. This URL is already in your sitemap. - 2Write these 4 sections (copy this structure):
• What is Documateo? — "A free online tool suite with 48+ PDF and image tools, no signup needed, no watermarks."
• Why I built it — Tell your real story. Why did you start this? What problem annoyed you?
• What makes us different — "Built in India, privacy-first, completely free for daily use."
• Contact — Add your email address. Real contact info builds E-E-A-T trust. - 3Aim for 200-300 words minimum. Don't worry about it being perfect — authentic is better than polished.
- 4Add a footer link to /about on every page. Google's E-E-A-T (Experience, Expertise, Authoritativeness, Trust) score improves when you do this.
💡 "E-E-A-T" is Google's way of deciding if a website is trustworthy. An About page with a real person's story dramatically improves your chances of ranking AND getting AdSense approved.
Add noindex tags to private pages
📋 Step-by-Step Guide — Hiding Private Pages from Google
⚠️ Why does this matter? Pages like /login and /dashboard shouldn't appear in Google search results. If they do, it looks unprofessional and wastes Google's crawl budget on pages that have no value to searchers.
- 1In your React app, for each private route, add this HTML tag inside the
<head>section:<meta name="robots" content="noindex, nofollow"> - 2Add this tag to these pages:
/login,/register,/dashboard,/billing,/admin,/security. - 3If you're using React Helmet or a meta management library, add it there. If you're managing meta tags directly in the component, add it to the component's head section.
- 4Also remove
/securityand/loginfrom yoursitemap.xmlfile entirely — private pages should never be in the sitemap. - 5Redeploy your site. Go to GSC → URL Inspection → test one of those private URLs → confirm it says "noindex".
💡 Google has a limited "crawl budget" for your site — it can only visit a certain number of pages per day. Wasting it on login pages means your tool pages get crawled less. noindex = protect your crawl budget.
Install Microsoft Clarity (free heatmaps + session recordings)
📋 Step-by-Step Guide — Setting Up Microsoft Clarity
⚠️ What is Clarity? It's a free tool by Microsoft that records your users' screen as they use your website. You can watch videos of real users using your tools — where they click, where they get confused, where they leave. Completely free, no limits.
- 1Go to clarity.microsoft.com — click "Get Started for Free". Sign in with any Microsoft account (Outlook, Hotmail, etc.).
- 2Click "Add new project". Enter: Project name =
Documateo| Website URL =https://documateo.com. Click Continue. - 3Clarity will give you a small JavaScript snippet (looks like:
<script>...</script>). Copy it. - 4Paste this snippet inside the
<head>tag of your website. Since you have a React app, add it to yourindex.htmlfile in thepublicfolder. - 5Deploy your site. Go back to Clarity — it will say "Waiting for data". Within a few hours of getting real visitors, it starts recording.
- 6After 3 days: Come back and watch 5 session recordings. Look for: where do users get confused? Where do they click that doesn't work? Where do they leave?
- 7Check Heatmaps for your most popular pages: /pdf/merge, /pdf/compress, /image/remove-bg. Dark red = lots of clicks, blue = ignored areas.
💡 Clarity shows you exactly where users "rage-click" (click multiple times in frustration) — that tells you exactly what to fix. It also shows which parts of the page users actually scroll to, so you know where to place ads.
Apply for Google AdSense
📋 Step-by-Step Guide — Applying for Google AdSense
⚠️ Apply AFTER creating your Privacy Policy and About pages. Without those, you'll be rejected immediately. Also make sure your site has real content (your 90 blog posts and 48 tools already qualify). There is NO minimum traffic requirement.
- 1Go to adsense.google.com — click "Get Started". Sign in with a Google account (use the same one you use for GSC for easier management).
- 2Enter your website URL:
https://documateo.com. Select Country:India. Select Currency:INR. Click Save and Continue. - 3You'll be given a verification snippet — a small piece of JavaScript code. Copy it.
- 4Paste this snippet into the
<head>tag of yourindex.html(in thepublicfolder). Deploy your site. This lets Google verify you own the website. - 5Important: Do NOT create ad slots yet. Just the verification snippet is enough. Wait for the approval email.
- 6Wait 7-14 days. Google will either: ✅ Approve you (you get an email) or ❌ Reject you with a specific reason. If rejected, read the email carefully — it tells you exactly what to fix. Common reasons: missing Privacy Policy, thin content, confusing navigation.
💡 AdSense doesn't require minimum traffic. They care about: 1) Real content (you have 90+ blog posts ✅), 2) Privacy Policy page ✅ (after you create it), 3) About page ✅, 4) No policy violations (no copyright content, no misleading claims). You already qualify!
📅 90-Day Goals
Month 1–3. The foundation sprint. Every task here compounds for months. By Day 90: AdSense approved, affiliate links live, 500–15,000 monthly visitors.
You have 48 tools and 90+ blog posts. The work now is: technical fixes, monetization setup, and building the daily habits that make SEO compound. Think of it like planting seeds — you won't see the harvest in week 1, but by month 3 you'll have daily organic visitors arriving without any effort.
Month 1 — Technical Foundation Most Critical
SEO Technical Fixes
✓
Fix React SPA rendering — Cloudflare Pages Function
✓
Fix Googlebot 403 — crawler whitelist in FastAPI middleware
Request indexing for all 102 pages (10/day over 10 days)
📋 Complete Guide — Getting All 102 Pages Indexed
⚠️ Why is this critical? A page can't rank in Google if it's not indexed first. "Indexed" means Google has read your page and saved it in their database. You have 102 pages but Google may only know about 34. You need to tell Google about the other 68 pages.
- 1Every morning, go to search.google.com/search-console → URL Inspection → paste 10 URLs → click "Request Indexing" for each.
- 2Day 1 (PDF Tools): /pdf/merge, /pdf/compress, /pdf/split, /pdf/protect, /pdf/unlock, /pdf/watermark, /pdf/pdf-to-word, /pdf/rotate, /pdf/flatten, /pdf/to-image
- 3Day 2 (Image Tools): /image/remove-bg, /image/compress, /image/resize, /image/crop, /image/convert, /image/watermark, /image/remove-exif, /image/bulk-resize, /image/flip, /image/aspect-crop
- 4Day 3 (Video + More PDF): /video/extract-audio, /video/video-to-gif, /pdf/redact, /pdf/delete-pages, /pdf/rearrange, /pdf/page-number, /pdf/add-text, /pdf/stamp, /pdf/extract, /pdf/remove-metadata
- 5Days 4-10: Submit blog posts, 10 per day. Priority blogs: comparison articles ("Documateo vs ilovepdf"), "Best free PDF tools India 2026", and all "how to" guides.
- 6Track which ones are indexed: Go to GSC → Coverage → "Valid" tab to see indexed pages. Update the GSC Indexing panel in this dashboard.
💡 Set a daily reminder at 9am: "Submit 10 URLs to GSC". It takes 5 minutes per day and the payoff is massive — each indexed page is another entry point for organic traffic.
Fix sitemap duplicate URLs (3 exact duplicates found)
📋 Step-by-Step Guide — Fixing Duplicate Sitemap URLs
⚠️ What's the problem? Your sitemap.xml has some URLs listed twice. When Google sees the same URL twice, it gets confused about which version to index. It can also split the "ranking power" between duplicates, hurting both pages.
- 1Open your sitemap.xml file in your code editor (it's usually in the
publicfolder or generated by your sitemap library). - 2Use Ctrl+F (Find) to search for:
how-to-remove-pdf-metadata— delete one of the duplicate entries. - 3Search for:
how-to-convert-video-to-gif— delete one of the duplicate entries. - 4Find and completely remove:
/securityand/loginfrom the sitemap. These are private pages and should never be in the sitemap. - 5Save the file and redeploy your site. Then resubmit the sitemap in GSC (Sitemaps → Resubmit).
💡 A clean sitemap with no duplicates = Google trusts your site more = faster and better indexing. 5 minutes of cleanup = months of better SEO performance.
Add noindex to private pages (/login, /dashboard, /register, /billing, /admin)
Add internal linking between tools (reverse-tool loop)
📋 Step-by-Step Guide — Building the Tool Loop
⚠️ What is a "tool loop"? ilovepdf shows you a "Next step" suggestion after every tool result. After you compress a PDF, it says "Now merge your PDFs?" After you merge, it says "Want to compress the merged file?" Users keep clicking and stay on the site 5+ pages per visit. This is their #1 retention strategy.
- 1After PDF Compress result page → add a link: "Now merge your PDFs? → PDF Merge →"
- 2After PDF Merge result → add: "Need to compress the merged file? → PDF Compress"
- 3After Image Remove BG result → add: "Now resize your image? → Image Resize"
- 4After PDF to Word result → add: "Need to convert back? → Word to PDF"
- 5Every tool should link to 2-3 related tools. Think about what someone naturally does next after using each tool.
- 6Style them as clean button-like links below the download button. Don't make them look like ads — make them look like helpful suggestions.
💡 Each internal link also passes "SEO authority" between pages — it tells Google that your pages are related and important. ilovepdf has been doing this for years and it's one of the main reasons they dominate search results.
Monetization Setup (Month 1)
Create Privacy Policy + Terms of Service pages
Apply for Google AdSense
Sign up for Adobe Acrobat affiliate (Impact.com) — ₹600–₹2,500/sale
📋 Step-by-Step Guide — Setting Up Adobe Affiliate
⚠️ What is affiliate marketing? You add a special link on your website. When someone clicks it and buys Adobe Acrobat, Adobe pays you a commission (₹600–₹2,500 per sale). You don't handle the product, shipping, or customer service. You just add a link.
- 1Go to impact.com → Click "Join as a Partner" → Create a Publisher account (you're a publisher — the website owner who promotes products).
- 2Fill in your details: Website URL = documateo.com, Category = Software/Technology, Monthly visitors = your current number (estimate is fine).
- 3Once your account is created, use the search bar inside Impact to search "Adobe" → Find "Adobe Acrobat" in the marketplace → Click "Apply".
- 4Wait 2-5 days for Adobe to approve your application. They look at whether your site is relevant to their product (PDF tools = very relevant ✅).
- 5Once approved, go back to Impact → Adobe program → get your unique affiliate link. It looks like a normal URL but has a tracking code in it.
- 6Place the link on your PDF tool pages: Add a small text at the bottom of every PDF tool page: "Need professional PDF editing? Try Adobe Acrobat →"
- 7Add to PDF blog posts naturally — contextual mentions convert 10× better than banners. Add a "Tools We Recommend" box at the end of each blog post.
- 8Add a disclosure at the top of every page with affiliate links: "This page contains affiliate links. If you buy through our links, we may earn a commission at no extra cost to you."
💡 You only need ONE person per month to buy Adobe through your link to earn ₹2,500. With 15,000+ monthly visitors on PDF pages, this is extremely achievable. Contextual links (in-text) convert 10-15× better than banner ads.
Sign up for Canva Pro affiliate (Image tools) — ₹500–₹1,800/sale
📋 Step-by-Step Guide — Setting Up Canva Affiliate
- 1Go to canva.com/affiliates → Click "Apply Now". Fill in your website details.
- 2Description tip: Write "I run Documateo.com, a free image and PDF tool website. My users often need design tools after processing their images."
- 3Wait 1-3 days for approval. Once approved, get your affiliate link from the Canva affiliate dashboard.
- 4Place it on your Image tool result pages: After Remove Background, Resize, Compress — add: "Want to design with your image? Try Canva Pro →"
- 5Add to image-related blog posts: "Best image tools India 2026", "How to compress images", etc.
💡 Canva has a massive brand recognition in India — your users already know and trust Canva. Mentioning it feels like a helpful suggestion, not a sales pitch. That's why conversion rates are high.
Add affiliate links to all 90+ blog posts (batch in one session)
📋 Strategy Guide — Adding Affiliate Links to Blog Posts
- 1Block out one 5-hour session to do all blog posts at once. Put on music, make tea, don't get distracted.
- 2Do all PDF blog posts first → add Adobe Acrobat affiliate link. Then all image blog posts → add Canva Pro affiliate link.
- 3Maximum 2 affiliate links per post — one naturally in the article body, one in a "Tools We Recommend" box at the very end.
- 4Never write "click here" — instead write the full product name: "Try Adobe Acrobat for professional PDF editing". Descriptive links convert much better.
- 5Add a short disclosure at the top of every blog post: "Disclosure: This post contains affiliate links. We may earn a small commission if you buy through our links, at no extra cost to you."
- 6After finishing, test a few links to make sure they work and your tracking code is in them.
💡 This is a "plant once, harvest forever" task. Spend 5 hours today, earn passive affiliate income every month for years without touching those posts again.
Month 2 — Traffic & Content Growth Phase
Place AdSense ads strategically once approved
📋 Guide — Placing AdSense Ads for Maximum Revenue
⚠️ Don't do this until you receive the approval email. Placing ad code before approval can get your account banned permanently.
- 1Week 1-2 after approval: Enable "Auto Ads" only. Go to AdSense → Ads → Overview → toggle on "Auto Ads". Let Google's AI test placements automatically. This is the safest way to start.
- 2After 2 weeks, go to AdSense → Reports → see which pages and placements earn the most. Manually replicate those positions on high-traffic pages.
- 3Best ad positions for tool sites: Above the upload area (users see it while the page loads), below the download button (users see it while downloading), between paragraphs 2 and 5 of blog posts.
- 4Best ad sizes: 728×90 leaderboard (desktop), 300×250 rectangle (sidebar), 320×50 mobile banner.
- 5Never place ads: Inside drag-and-drop zones, as popups, or in a way that covers content. These are policy violations that can get you banned.
💡 Start with Auto Ads. Let Google do the testing for 2 weeks. You'll earn less at first, but you'll learn which placements actually work for your specific users. Then manually optimize based on real data.
Set up email capture with Brevo (free — 300 emails/day)
📋 Step-by-Step Guide — Building Your Email List with Brevo
⚠️ Why build an email list? Google can change its algorithm and your traffic can drop overnight. Your email list is the ONE asset no algorithm can take away. Even 500 engaged subscribers is more valuable than 10,000 anonymous visitors.
- 1Go to brevo.com → Sign up for free. Free plan includes: 300 emails/day, up to 1,000 contacts, email automation. No credit card needed.
- 2Go to Contacts → Create a new list called "Documateo Users".
- 3Go to Forms → Create a new form. Keep it simple: just Email field + "Email me my result" button. No name field needed — fewer fields = more sign-ups.
- 4Best capture moment: After a user processes a file, show: "Email this result to yourself? [email field] [Send]". This feels like a useful feature, not a signup form. Conversion rate is very high.
- 5In Brevo → Automations → Create a Welcome sequence:
• Day 0: "Thanks for using Documateo! Here's your file + [link to your most popular tool]"
• Day 3: "Pro tip: Did you know you can also [compress/merge/etc.]? [tool link]"
• Day 7: "Documateo PRO removes ads and lets you process unlimited files for ₹199/month. [upgrade link]" - 6Get the Brevo API key or use their form embed code to integrate with your React app.
💡 Logged-in users convert to PRO at 4× the rate of anonymous users. An email list also enables you to announce new features, which brings back repeat users.
Write 4 competitor-targeting blog posts (1 per week)
📋 Guide — Writing Competitor Alternative Blog Posts
⚠️ Why target competitor keywords? People searching "ilovepdf alternative" are already looking for something better — they're the EASIEST traffic to convert because they already want to switch. This is the single most valuable content strategy for tool websites.
- 1Week 1: Write "Best Smallpdf Alternatives — Free in 2026". Structure: Why people leave Smallpdf (hourly limits, watermarks) → List of alternatives → Why Documateo is the best free option. Target keyword: "smallpdf alternative free".
- 2Week 2: Write "Best ilovepdf Alternative Without Ads". Structure: Why ilovepdf has ads → Alternatives → Documateo as the ad-light option. Target keyword: "ilovepdf alternative no ads".
- 3Week 3: Write "Best Free PDF Tools in India 2026". India-specific search, very low competition. Include: tool comparison table, pricing, ease of use for Indian users.
- 4Week 4: Write "How to Compress PDF on Mobile (Free)". Mobile-specific, underserved keyword. Focus on: using Documateo on phone, Android/iOS tips.
- 5Blog post structure for best results: H1 title (keyword) → Introduction (problem) → Comparison table → Detailed review of each option → CTA to use Documateo → FAQ section (use real Google questions). Aim for 1,500+ words.
💡 You can write each post in 2-3 hours. Use ChatGPT to generate a first draft, then edit it to add real insights and your personal voice. AI content + human editing = fast content production.
Implement PRO upgrade friction-point triggers in the app
📋 Developer Guide — Implementing PRO Upgrade Triggers
⚠️ Key principle: NEVER block the free tool. Let free users complete their task. The upgrade prompt is a helpful suggestion, not a wall. Blocking access = users leaving forever. Gentle suggestions = conversions.
- 1Trigger 1 — File size limit: If uploaded file > 10MB, show a non-blocking banner: "Your file is 15MB. We'll process it, but PRO users get unlimited file sizes. [Upgrade for ₹199/month]". Still process the file.
- 2Trigger 2 — 3rd tool use today: Track tool usage in localStorage. When a user opens their 3rd tool in one day, show a gentle banner at top: "You're really putting Documateo to work today! 💪 PRO removes limits and ads. [Try free for 7 days]".
- 3Trigger 3 — Batch upload attempt: If user tries to upload 4+ files and they're on free plan: "Batch processing is a PRO feature — ₹199/month. [Try PRO free for 7 days]". Block this one.
- 4Trigger 4 — After high-value tool use: After Remove BG or PDF to Word result, show: "Liked this? PRO = unlimited uses + no ads + batch processing. Starting at ₹199/month. [Start free trial]".
- 57-day free trial setup in Razorpay: Go to Razorpay dashboard → Subscriptions → Plans → Edit your plan → Enable Trial Period → set 7 days. This alone gives 3-5× conversion rate increase.
💡 The best SaaS companies show upgrade prompts at moments of HIGH engagement (when users clearly find value) not at moments of FRUSTRATION. "You just removed the background from 3 images! PRO lets you do 100/day" converts better than "You've hit your limit".
Write 2 Hindi blog posts for top tools
📋 Guide — Hindi Blog Strategy (India-First Advantage)
⚠️ Why Hindi? Millions of Indians search Google in Hindi. ilovepdf and Smallpdf have ZERO Hindi content. You could rank #1 for popular Hindi searches with almost zero effort because no competitor is targeting these keywords.
- 1Post 1: "PDF compress kaise kare free mein" (How to compress PDF for free). Write a simple, clear guide in Hindi. Use Documateo as the recommended tool throughout.
- 2Post 2: "PDF merge karna sikhe free mein" (Learn to merge PDF for free). Same format.
- 3Writing in Hindi: If your Hindi is not strong, use Google Translate on your English posts + manual editing for natural-sounding language. Or use ChatGPT: "Write this blog post in simple, clear Hindi".
- 4Use Hindi keywords naturally in the H1 and first paragraph. Google understands Hindi very well.
- 5After publishing, request indexing for these URLs in GSC.
💡 There are 500+ million Hindi internet users in India. A single Hindi article that ranks #1 for a popular search can bring thousands of visitors per month. Competition is near-zero because all your competitors are English-only Western companies.
Month 3 — Scale & Consolidate Milestone Month
Apply for Ezoic when GA4 hits 10,000 sessions/month
📋 Guide — Upgrading from AdSense to Ezoic
⚠️ What is Ezoic? It's an ad network that uses AI to test thousands of different ad placements and sizes to maximize your revenue. Most websites see 2-3× more revenue per visitor compared to AdSense alone. Minimum requirement: 10,000 sessions/month.
- 1Set a weekly Monday reminder to check GA4: Home → Users → Sessions this month. When you see 10,000+ sessions in any single month → apply immediately.
- 2Go to ezoic.com → Apply as publisher → Enter your website URL → Connect your Google Analytics → Submit.
- 3Ezoic integration: They'll ask you to add their script to your site. This takes about 30 minutes. Their support team helps you through the process.
- 4Ezoic's AI will automatically start testing different ad configurations. Give it 2-4 weeks to learn your site's patterns. Revenue will improve each week.
💡 At 10,000 sessions with AdSense: ~₹3,000-5,000/month. Same 10,000 sessions with Ezoic: ~₹7,000-12,000/month. Same traffic, 2-3× more money. This is the most impactful single action you'll take in Month 3.
Launch Developer API with API key auth
Ship 10 new tools from Phase 1 & 2 of roadmap
Join CJ Affiliate for Notion + Grammarly links
📋 Guide — CJ Affiliate for Productivity Tools
- 1Go to cj.com (Commission Junction) → Sign up as a publisher → Enter documateo.com as your website.
- 2Search for "Notion" and "Grammarly" in the advertiser marketplace → Apply to each program.
- 3Where to place Grammarly links: On your PDF to Word conversion page — after converting, mention "Clean up grammar in your Word doc with Grammarly".
- 4Where to place Notion links: On your blog about document workflows — "Organize your documents better with Notion".
💡 Grammarly pays up to ₹1,500 per free sign-up, not just paid conversions. It's one of the highest-paying affiliate programs per action.
📈 6-Month Plan
Month 4–6. SEO compounds. Ad revenue scales with traffic. PRO conversions increase. Target: ₹46,000–₹1,23,000/month by Month 6.
Month 4–6 Milestones
Month 4
15,000–30,000 Monthly Visitors
AdSense + Ezoic running. Affiliate income from Adobe + Canva established. First PRO subscribers. Revenue: ₹9,500–₹27,000/month.
Month 5
30,000–60,000 Monthly Visitors
Apply for Mediavine if sessions hit 50,000. Developer API launched. 60+ tools live. Revenue: ₹21,000–₹51,000/month.
Month 6
60,000–1,20,000 Monthly Visitors
Multiple affiliate programs running. PRO subscriptions stable. Hindi content driving significant India traffic. Revenue: ₹46,000–₹1,23,000/month.
Month 4-6 Key Tasks
Apply for Mediavine at 50,000 sessions/month
Build Chrome Extension — right-click PDF & image tools
Rank in top 10 for "ilovepdf alternative" and "smallpdf alternative"
Launch Tool Pipeline feature — chain multiple tools in one flow
Ship full video suite (Trim, Mute, Rotate, Speed, Merge)
Reach 85+ total tools live
🎯 1-Year Vision
Month 7–12. Sustainable revenue engine. Multiple income streams. Brand recognition in India.
Monthly Visitors
1.2L+
Organic SEO compound growth
Monthly Revenue
₹1.5L
Ads + Affiliate + PRO subs
Tools Live
85+
Complete Phase 1-3 roadmap
Chrome Extension
10k
Users · Long-term moat
Month 7–9 Priorities
Build Chrome Extension — PDF & Image tools in browser
📋 Guide — Building the Documateo Chrome Extension
⚠️ Why a Chrome Extension? ilovepdf's Chrome extension + WordPress plugin = 2 million backlinks from 26,000 different websites. Every user who installs your extension promotes your brand every time they use Chrome. It's a compounding marketing machine.
- 1Core feature: Right-click any image on any webpage → "Open in Documateo" → Compress, Remove BG, Resize. No download needed.
- 2Core feature: Right-click any PDF link → "Process with Documateo" → Merge, Compress, Convert.
- 3Core feature: Extension popup — quick tool launcher with your last 5 operations shown. One-click access to any tool.
- 4Publish to Chrome Web Store: One-time $5 developer fee. Review takes 1-3 days. Make a compelling store listing with screenshots.
- 5Promote on ProductHunt, Reddit r/Chrome, tech Twitter. A Chrome Extension launch on ProductHunt can bring thousands of visitors overnight.
💡 The Chrome Extension is the #1 long-term moat you can build. Once users install it, Documateo becomes part of their daily browser. Uninstall rate is very low. And it generates backlinks automatically as other sites mention it.
Apply for Mediavine at 50,000 sessions/month
Ship full video suite (Trim, Mute, Rotate, Speed Change, Merge)
Launch Tool Pipeline / Chain feature (PRO)
Build WordPress plugin (like ilovepdf's backlink machine)
Month 10–12 Priorities
Launch Free API tier (developer acquisition + backlinks)
Target enterprise / B2B customers with Team plan
Rank top 10 for "ilovepdf alternative" and "smallpdf alternative"
Reach 85+ tools — complete Phase 1-3 roadmap
⛔ What NOT to Build Yet
OCR (Image to Text)
Tesseract on Railway is 10–30s per page. Will generate timeouts and 1-star reviews. Build when: Celery/Redis job queue is added. Currently the user experience would be terrible.
AI-Powered Tools (OpenAI / Claude API)
Costs ₹2–5 per operation. Unsustainable until PRO revenue is stable at ₹50k+/month. Build when: PRO revenue comfortably covers API call costs.
Office File Conversion (LibreOffice)
+800MB Docker image. Crash-prone. Slow. PyMuPDF already handles most conversion cases. Build when: Dedicated processing worker instance.
Video Transcription / Subtitles (Whisper)
Whisper model is 1.5GB+. Will crash Railway free tier instantly (OOM error). Build when: Dedicated GPU worker or paid API like AssemblyAI.
Async Job Queue (Celery + Redis)
Significant operational complexity. Premature at current scale. Build when: Video compression jobs start timing out regularly (you'll know when).
💰 Monetization
Three revenue streams: Display Ads, Affiliate Income, PRO Subscriptions. Start all three now — they grow together and protect you if one underperforms.
💡 How Documateo Makes Money (Overview for Beginners)
Your website earns money in 3 ways simultaneously:
1
Display Ads (Google AdSense): Google shows ads on your pages. You earn every time someone views or clicks them. Passive — no work needed after setup. Earns: ₹50–₹200 per 1,000 visitors.
2
Affiliate Links: You recommend products (Adobe Acrobat, Canva Pro). When users buy through your link, you get a commission. One-time work, permanent passive income. Earns: ₹500–₹2,500 per sale.
3
PRO Subscriptions: Users pay ₹199/month for unlimited access, no ads, batch processing. Direct revenue. Earns: ₹199/month per subscriber, recurring forever.
Step 1 — Google AdSense Setup
Create Privacy Policy page at /privacy-policy
Create Terms of Service page at /terms-of-service
📋 Quick Guide — Terms of Service
- 1Go to termsofservicegenerator.net or use the same privacypolicygenerator.info site — it also generates Terms of Service.
- 2Enter: Website name = Documateo, URL = https://documateo.com.
- 3Copy the generated text → create page at /terms-of-service → add footer link.
Write About page (200+ words, founder story)
Apply for Google AdSense
Enable Auto Ads once approved by AdSense
📋 Guide — Enabling Auto Ads
- 1Go to adsense.google.com → click "Ads" in the left sidebar → click "Overview".
- 2You'll see an "Auto ads" toggle — turn it ON.
- 3Make sure the AdSense code snippet (from when you applied) is still on every page of your site. Auto Ads uses this same code to show ads.
- 4Within 30-60 minutes, ads will start appearing automatically on your site. Google's AI decides the best placements.
- 5After 2 weeks, check "Reports" to see which pages and placements earn the most, then manually optimize those spots.
💡 Start with Auto Ads. Let Google's AI learn your site for 2-4 weeks before manually placing ad units. This gives you a baseline to compare against.
Install Microsoft Clarity for heatmaps (shows where users actually look)
Step 2 — Affiliate Income
Sign up: Adobe Acrobat affiliate (Impact.com) — ₹600–₹2,500/sale
Sign up: Canva Pro affiliate — ₹500–₹1,800/sale
Add affiliate links to all 90+ blog posts
Join CJ Affiliate (cj.com) for Notion + Grammarly links
Add "Tools We Recommend" section to every blog post
📋 Guide — Creating the "Tools We Recommend" Box
- 1At the very end of every blog post (after conclusion, before comments), add a styled box titled "🛠️ Tools We Recommend".
- 2For PDF posts: List 1-2 affiliate products + link to relevant Documateo tools. Example: "Adobe Acrobat [affiliate link] | Documateo PDF Compress [internal link]".
- 3Make it look like a genuine recommendation, not an ad. Use a light-colored box with icons. Readers who reach the end of a blog post are engaged — they convert.
- 4Create this as a reusable React component so you can add it to any blog post with one line of code. Pass the affiliate category (pdf/image/video) as a prop and it automatically shows the right recommendations.
Step 3 — PRO Subscriptions (₹199/month)
Implement file size limit trigger (free: 10MB → PRO: unlimited)
📋 Guide — File Size Limit Implementation
⚠️ Important: Process the file anyway. Show the suggestion as a friendly banner, not a block. Blocking = user leaves forever. Suggesting = user considers upgrading.
- 1In your file upload handler (frontend), check the file size before uploading:
if (file.size > 10 * 1024 * 1024)— this checks if file is over 10MB. - 2If over 10MB AND user is not PRO: Show a banner at top of page: "📁 Your file is [X]MB. We're processing it! PRO users get unlimited file sizes, no ads, and batch processing for ₹199/month. [Try PRO free for 7 days]".
- 3Still upload and process the file. The suggestion is helpful, not a barrier.
- 4Track the conversion: How many users who see this banner click the PRO link? Use GA4 events to measure.
Implement 3rd-tool-use-today non-blocking banner
Block batch upload for free users with PRO prompt
Add post-download PRO suggestion for Remove BG + PDF to Word
Enable 7-day free trial in Razorpay (3–5× conversion boost)
📋 Guide — Setting Up the 7-Day Free Trial
⚠️ Why does a free trial matter so much? "Try PRO free for 7 days" converts 3-5× better than "Upgrade for ₹199/month". Users feel less risk. Most who try PRO don't cancel — they experience the value and keep paying.
- 1Log into your Razorpay dashboard → Click "Subscriptions" in the left sidebar.
- 2Find your existing subscription plan → Click "Edit Plan".
- 3Look for "Trial Period" setting → Enter: 7 days. Save changes.
- 4Update all your upgrade prompts to say: "Try PRO FREE for 7 days → Then ₹199/month".
- 5You do not charge users during the trial. After 7 days, Razorpay automatically charges them if they don't cancel. Most don't cancel.
Step 4 — Email List (Your Most Valuable Asset)
Set up Brevo account (free — 300 emails/day, 1,000 contacts)
Add "Email your result" capture after file processing
Build 3-email welcome sequence in Brevo
Add "Save file history — create free account" capture flow
🔍 SEO & Blog
Technical SEO fixed. Now: content, internal links, and blog strategy. SEO is a long game — consistency beats intensity.
Technical SEO is fixed. Google can read all 48 tools + 90 blogs. Breadcrumbs and Review Snippets already showing in GSC. Now focus on content quality and internal linking — these are the only two things that drive ranking improvements from here.
🔍 How SEO Works (Explained for Beginners)
SEO (Search Engine Optimization) means making your website appear higher in Google search results. When someone types "compress PDF free" into Google, you want your website to appear on page 1. Here's how Google decides rankings:
1
Indexing: Google first needs to read and save your page. Without being indexed, you can't rank. (You're fixing this now with GSC requests.)
2
Relevance: Does your page content match what the user searched for? Your title, headings, and content should use the exact keyword the user searched.
3
Authority: Does Google trust your website? Trust comes from other websites linking to you (backlinks) and from having lots of quality content.
4
SEO is slow but compounding: Work you do today pays off in 3-6 months. But once you rank, you get free visitors every day without paying for ads.
Technical SEO — Week 1
✓
Fix React SPA rendering — Cloudflare Pages Function
✓
Fix Googlebot 403 — FastAPI crawler whitelist
Request indexing: 102 pages at 10/day in GSC
Fix sitemap: remove exact duplicates + /security + /login
Add noindex to private pages
Resubmit sitemap.xml in GSC after fixes
Internal Linking — Month 1
Add reverse-tool links after every tool result
Link each tool page to its corresponding blog post
📋 Guide — Tool Page → Blog Post Linking
⚠️ What is internal linking? When one page on your website links to another page on your website. Google uses these links to understand which pages are related and which are important. More internal links to a page = Google thinks it's more important = better ranking.
- 1On your PDF Compress tool page → add a section: "📖 Learn more: How to Compress PDF Without Losing Quality →"
- 2On PDF Merge tool page → link to: /blog/how-to-merge-pdf-files-online-complete-guide
- 3On Image Remove BG tool → link to: blog posts about image editing, Canva alternatives, etc.
- 4Do this for every tool → link to its most relevant blog post. This is a one-time task that pays SEO dividends forever.
💡 Think of internal links as "votes of confidence" from one page to another. Your tool pages already get visitors — those visitors clicking to your blog posts tells Google "this blog post is worth reading".
Link each blog post back to its tool page with a CTA button
📋 Guide — Blog Post → Tool CTA
- 1At the end of every blog post, add a prominent CTA (Call-to-Action) button: "🔧 Try Documateo's Free PDF Compressor →" linking to /pdf/compress.
- 2Also add a mid-article mention after you explain the process: "You can do this for free with Documateo's PDF Compressor."
- 3Style the CTA as a colored button — not just a text link. Colored buttons get 10× more clicks than text links.
- 4This converts organic blog readers into tool users who then might upgrade to PRO. The blog → tool → PRO funnel is your highest-value conversion path.
Blog Content — Month 2–3
Write: "Best Smallpdf alternatives free 2026"
Write: "Best ilovepdf alternative no ads"
Write: "Best free PDF tools India 2026" (low competition)
Write: "PDF compress kaise kare" (Hindi — near-zero competition)
Write: "PDF merge karna free" (Hindi)
Update top 10 blog posts: add H2 subheadings, FAQ section, word count 1,500+
📋 Guide — Improving Existing Blog Posts
⚠️ Why improve existing posts? Google ranks "comprehensive" content higher. A 500-word post rarely ranks for anything. A 1,500+ word post with clear sections and FAQs that covers a topic completely = much better chance of ranking page 1.
- 1Find your top 10 posts: Go to GSC → Performance → Pages → sort by Impressions (most views). These are the ones Google already knows about — improving them has the highest ROI.
- 2Open each post. Count the words. If under 1,200 words → expand with more details, step-by-step instructions, examples.
- 3Add H2 subheadings: Break the article into clear sections. Each H2 should answer a specific question. Google uses headings to understand what a page is about.
- 4Add FAQ section at the bottom: Find what people ask about your topic. Go to Google → search your keyword → scroll down to "People Also Ask". Add those questions as FAQs with short answers. This often gets you featured in Google's special "FAQ" snippets (shown above regular results).
- 5After editing, go to GSC → URL Inspection → request re-indexing for that URL. Google will re-read and potentially rank it higher.
🔍 SEO Rankings Target — Top 10 Search Volumes
| # | Keyword / Tool | Monthly Searches | Competition | Status |
|---|---|---|---|---|
| 1 | PDF to Word | 2.1M | Low | Live ✅ |
| 2 | Remove Background | 1.2M | Low | Live ✅ |
| 3 | Video Compress | 800K | Medium | Build |
| 4 | Extract Audio MP4→MP3 | 700K | Low | Live ✅ |
| 5 | PDF to Text | 600K | Zero | Live ✅ |
| 6 | Flatten PDF | 500K | Zero | Live ✅ |
| 7 | Video to GIF | 400K | Low | Live ✅ |
| 8 | Video Trim | 380K | Medium | Build |
| 9 | PDF Grayscale | 250K | Zero | Build |
| 10 | EXIF Remover | 450K | Zero | Live ✅ |
🔧 Tool Roadmap
Competitor-benchmarked against iLovePDF (25+ tools) and Smallpdf (20+ tools). Every item below is a search query you're missing. Tick each tool as you ship it.
Already Live
14
PDF + Image + Video tools
Zero New Dependencies
14
Ship with existing libraries
One Library Needed
8
pip install only
Total Roadmap
47
Across 5 phases
Competitor gap analysis: iLovePDF has PDF Repair, Add Page Numbers, PDF Redact, PDF Annotate, OCR, e-Sign, and PDF Translate. Smallpdf has PDF Editor and eSign. These are the exact tools users search for after finding your basic tools — and they go to a competitor if you don't have them. Ship Phase 2 first — zero new dependencies, maximum traffic gain.
✅ Phase 1 — Already Live Tick what you've shipped
PDF Compressor
PDF Merger
PDF Splitter
PDF Password Protect
PDF Unlock / Remove Password
PDF Rotate Pages
PDF Watermark
Image Compressor
Image Resize
Image Format Converter (JPG / PNG / WebP)
Image Crop
Image Watermark
Extract Audio from Video — 700K searches/month
📋 How it was built
- 1FastAPI endpoint runs:
ffmpeg -i input.mp4 -vn -acodec mp3 output.mp3on the uploaded file and returns the MP3 as a download. - 2Also offer AAC:
-acodec aac output.aac— better quality at smaller size than MP3. - 3Companion idea: "Mute Video" (strip audio entirely):
ffmpeg -i input.mp4 -an output.mp4— add as a second quick tool.
Video to GIF — 400K searches/month (ffmpeg palette trick)
📋 How it was built
- 1Two-step ffmpeg for best quality: Step 1 — generate a colour palette from the video:
ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos,palettegen" palette.png - 2Step 2 — use the palette to create a high-quality GIF:
ffmpeg -i input.mp4 -i palette.png -filter_complex "fps=10,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif - 3The palette method = 60–70% smaller file with much better colours vs direct conversion. Let user choose FPS (5/10/15) and max width (320/480/640px).
🚀 Phase 2 — Zero Dependency Wins Ship This Week · Existing Libraries Only · Zero Cost
⚙️ One-time Setup — Add ffmpeg + poppler-utils to Dockerfile (10 min total)
📋 How to Do It — Dockerfile Setup
- 1Open your Dockerfile in your code editor. Find the line:
apt-get install -y ghostscript imagemagick - 2Change it to:
apt-get install -y ghostscript imagemagick ffmpeg poppler-utils— just add those two packages at the end of that same line. - 3Commit and push to GitHub. Railway will auto-rebuild and redeploy. Takes 3–5 minutes. That's it.
- 4ffmpeg = enables all video tools (compress, trim, watermark, mute, rotate). poppler-utils = enables PDF-to-image rendering. Both are free open-source packages, zero cost increase on Railway.
PDF to Text — 600K searches/month (5 lines of code)
📋 How to Build — PDF to Text
- 1Backend:
import fitz; doc = fitz.open(file_path); text = "\n\n--- Page {i+1} ---\n".join([page.get_text() for i, page in enumerate(doc)]) - 2Return as downloadable
.txtfile via FastAPIFileResponse. Also add a "Copy to clipboard" button on the frontend for short PDFs. - 3Handle scanned PDFs: if extracted text is fewer than 20 chars/page, show — "This looks like a scanned PDF. Use our OCR tool for best results." with a direct link to OCR.
- 4Total build time: ~45 minutes including frontend upload/download UI.
Flatten PDF — 500K searches/month (5 lines of pikepdf)
📋 How to Build — Flatten PDF
- 1What it does: Bakes all interactive form fields (checkboxes, text fields, signatures) into the page as static, uneditable content. Used by accountants, lawyers, and HR teams for official documents.
- 2Backend option A (pikepdf):
import pikepdf; pdf = pikepdf.open(input_path); pdf.save(output_path, flatten_annotations=True) - 3Backend option B (PyMuPDF — often better):
import fitz; doc = fitz.open(path); doc.bake(); doc.save(output_path)— PyMuPDF'sbake()flattens all annotations and widgets in one call. - 4Frontend: show a bold warning — "⚠️ This action is permanent. The flattened PDF cannot be edited." Users need this before they proceed. Total build time: ~45 minutes.
Flip Image — Simple completion of suite (1 line)
📋 How to Build — Flip Image
- 1Horizontal flip (mirror):
Image.open(path).transpose(Image.FLIP_LEFT_RIGHT).save(output) - 2Vertical flip (upside down):
Image.open(path).transpose(Image.FLIP_TOP_BOTTOM).save(output) - 3Offer both on one page as two buttons. Show live preview after flip. Total build time: 20–30 minutes.
EXIF Remover — 450K searches/month (5 min to build)
📋 How to Build — EXIF Remover
- 1The trick: Pillow strips all EXIF metadata automatically when you re-save without the exif param:
from PIL import Image; img = Image.open(path); img.save(output_path)— literally 2 lines. - 2Show what was removed (key UX): Before saving, read EXIF:
exif = img._getexif(). Map tag IDs to readable names. Show a summary: "GPS Location ✓ removed", "Camera: iPhone 15 ✓ removed", "Date taken: 12 Jan 2025 ✓ removed". - 3If GPS data was present, highlight in orange: "⚠️ This image contained GPS coordinates revealing your exact location — permanently removed." This creates a viral "wow" moment users want to share.
- 4Total build time: ~45 minutes. The EXIF display UI takes longer than the actual removal.
Remove PDF Metadata — Privacy tool for journalists + lawyers
📋 How to Build — PDF Metadata Remover
- 1Read metadata first:
import pikepdf; pdf = pikepdf.open(path); meta = dict(pdf.docinfo)— gives Author, Creator, Producer, CreationDate, ModDate, Company etc. - 2Clear all metadata:
pdf.docinfo = {}; pdf.save(output_path) - 3Show before/after table on frontend: "Author: John Smith → Removed ✓", "Software: Microsoft Word 2019 → Removed ✓". Makes the tool feel powerful and worth bookmarking.
- 4Total build time: ~45 minutes.
Images to PDF — 1.1M searches/month
📋 How to Build — Images to PDF
- 1Backend: Accept multiple images:
from PIL import Image; images = [Image.open(f).convert('RGB') for f in file_list]; images[0].save(output_path, save_all=True, append_images=images[1:]) - 2Frontend — drag to reorder: Show thumbnail previews after upload. Use @dnd-kit/sortable (free:
npm install @dnd-kit/core @dnd-kit/sortable) for drag-and-drop page ordering before converting. - 3Options: Page size (A4 default / Letter / Original image size). Margin (None / 5mm / 10mm).
- 4Free: up to 5 images. PRO: unlimited. Natural upgrade trigger for users combining 10+ scanned pages. Total build time: ~2 hours.
PDF to Image (JPG / PNG) — 800K searches/month
📋 How to Build — PDF to Image
- 1Backend:
import fitz; doc = fitz.open(pdf_path); pix = doc[0].get_pixmap(matrix=fitz.Matrix(2, 2)); pix.save(output_path)— Matrix(2,2) = 2× zoom = 144 DPI, high quality. - 2Multi-page: convert all pages → zip them:
import zipfile; with zipfile.ZipFile(zip_path, 'w') as zf: [zf.write(img, f"page-{i+1}.jpg") for i, img in enumerate(image_files)] - 3Options: Format (JPG default / PNG for transparency), DPI (72 = screen, 150 = standard, 300 = print). Single page → image download. Multi-page → ZIP.
- 4Total build time: ~1.5 hours.
PDF Repair — 380K searches/month
📋 How to Build — PDF Repair
- 1pikepdf opens corrupt PDFs tolerantly and re-saving fixes most corruption (bad cross-reference tables, invalid object streams):
pdf = pikepdf.open(path, suppress_warnings=True); pdf.save(output_path) - 2Wrap in try/except. If pikepdf fails, try PyMuPDF as fallback:
doc = fitz.open(path); doc.save(output_path)— PyMuPDF is often more tolerant of severely damaged files. - 3If both fail: return "This file is too severely damaged to repair automatically. It may have been truncated during download."
- 4Show file size before/after and: "Repair complete — recovered X pages." Total build time: ~1 hour.
Add Page Numbers to PDF — 290K searches/month
📋 How to Build — Add Page Numbers
- 1Backend:
for i, page in enumerate(doc): w = page.rect.width; h = page.rect.height; page.insert_text((w/2 - 10, h - 20), str(i+1), fontsize=10, color=(0,0,0)) - 2Options to offer: Position (bottom-centre / bottom-right / bottom-left), Format ("1" / "Page 1" / "1 of 10"), Starting number (default: 1), Font size (8 / 10 / 12).
- 3Add "Skip first page" checkbox — useful for documents with a cover page. Total build time: ~1.5 hours including options UI.
Reorder / Rearrange PDF Pages — Drag and Drop
📋 How to Build — PDF Page Reorder
- 1Backend: Accepts PDF + new page order array e.g. [2,0,1,3]:
new_pdf = pikepdf.Pdf.new(); [new_pdf.pages.append(pdf.pages[i]) for i in new_order]; new_pdf.save(output) - 2Frontend step 1: User uploads PDF → backend renders each page as small thumbnail (PyMuPDF at Matrix(0.5, 0.5)) → returns array of thumbnail URLs.
- 3Frontend step 2: Show thumbnails in grid. Use
@dnd-kit/sortable(free) for drag-and-drop reordering. Show page number badge on each thumbnail. - 4Add Delete (✕) button on each thumbnail — removes a page. This turns "reorder" into a full "page organiser" tool.
- 5When user clicks "Save", send new index array to backend. Total build time: ~4 hours — complex UI, but extremely high value and conversion.
Aspect Ratio Crop — 1:1, 16:9, 4:5 for social media creators
📋 How to Build — Aspect Ratio Crop
- 1Presets: Instagram Square (1:1), YouTube Thumbnail (16:9), Instagram Story / TikTok (9:16), Twitter/X Header (3:1), LinkedIn (1.91:1).
- 2Backend centre-crop logic:
target = 16/9; r = w/h; if r > target: new_w = int(h * target); left = (w-new_w)//2; img = img.crop((left, 0, left+new_w, h)) - 3Show preview of each preset. Offer manual crop canvas as PRO feature. Total build time: ~2 hours.
PDF Crop (trim page margins) — iLovePDF has this
📋 How to Build — PDF Crop
- 1pikepdf crop box:
page = pdf.pages[0]; page.CropBox = pikepdf.Array([left, bottom, right, top])— coordinates in PDF points (72 per inch). - 2Presets: "Remove all white margins" (auto-detect content bounds), "Small 5mm", "Standard 10mm", "Custom".
- 3Auto-detect content: use PyMuPDF —
bbox = page.get_bboxlog()to find where actual content is, then crop to that bounding box. Total build time: ~2 hours.
📦 Phase 3 — One pip Install Each Weeks 2–3 · Massive Traffic Gains
Remove Background — 1.2M searches/month (pip install rembg ~30MB)
📋 How to Build — Background Remover
- 1Add to requirements.txt:
rembg. ~30MB, CPU-only — no GPU needed, works on Railway free and paid plans. - 2Backend:
from rembg import remove; from PIL import Image; input_img = Image.open(file_path); output_img = remove(input_img); output_img.save(output_path, format='PNG')— always PNG (JPG can't store transparency). - 3First run downloads AI model (~170MB) automatically. Cached on Railway after first deploy. Warn on first use: "First use may take 15 seconds while the AI model loads."
- 4Frontend — before/after slider: Use
react-compare-slider(free npm) for a draggable divider showing original vs result. This dramatically increases perceived quality and social sharing. - 5Add "Replace background colour" option — user picks a colour, fill transparent area before download. Essential for product photography use case. Total build time: ~3 hours.
Video Compressor — 800K searches/month (ffmpeg CRF encode)
📋 How to Build — Video Compressor
- 1ffmpeg command:
ffmpeg -i input.mp4 -vcodec libx264 -crf 28 -preset fast output.mp4. CRF scale: 18 = high quality → 35 = smallest file. CRF 28 = good balance, ~50% reduction. - 2Offer 3 preset buttons: Low (CRF 22), Medium (CRF 28, default), High (CRF 34). Show estimated output size next to each preset.
- 3Important: Video compression is CPU-intensive. A 100MB video takes 30–60 seconds. Use FastAPI BackgroundTasks for async processing and poll for completion every 2 seconds. Show a spinner with "Processing your video…".
- 4Free: max 50MB input. PRO: max 500MB. Strong natural upgrade trigger for video creators. Total build time: ~3 hours including async progress UI.
PDF to Word — 2.1M searches/month (single biggest SEO opportunity)
📋 How to Build — PDF to Word
- 1Add to requirements.txt:
pdf2docx(handles layout, tables, and formatting far better than manual PyMuPDF extraction). - 2Primary approach:
from pdf2docx import Converter; cv = Converter(pdf_path); cv.convert(docx_path); cv.close() - 3Fallback (if pdf2docx fails): PyMuPDF's
.get_text('html')gets you 80% of the way — add python-docx to write the output as a proper .docx file. This is the #1 searched PDF tool globally. - 4UX disclaimer on frontend: "Conversion quality depends on the PDF structure. Scanned PDFs need OCR first. Complex layouts may not convert perfectly." Prevents support complaints.
- 5Free: convert 1 page. PRO: full document. Total build time: ~2 hours.
Word to PDF — 1.5M searches/month
📋 How to Build — Word to PDF
- 1Dockerfile: Add
RUN apt-get install -y libreoffice. ~300MB but converts Word → PDF perfectly, better than any Python-only library. - 2Backend:
import subprocess; subprocess.run(['libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', output_dir, input_path], check=True) - 3LibreOffice also handles .pptx → PDF, .xlsx → PDF, .odt → PDF — one Dockerfile line enables 4 additional tools at no extra cost.
- 4Accept .docx, .doc, and .odt files. Total build time: ~1.5 hours including Dockerfile change and testing.
PDF to Excel — 900K searches/month
📋 How to Build — PDF to Excel
- 1Add to requirements.txt:
pdfplumberandopenpyxl. - 2Backend:
import pdfplumber, openpyxl; wb = openpyxl.Workbook(); ws = wb.active; with pdfplumber.open(pdf_path) as pdf: [ws.append(row) for page in pdf.pages for table in page.extract_tables() for row in table]; wb.save(xlsx_path) - 3Edge case: if no tables detected, fall back to plain text extraction written as single-column Excel. Tell user: "No tables detected — extracted as plain text."
- 4Primary use: bank statements, invoices, financial reports. Very high PRO conversion. Total build time: ~2 hours.
PDF to PowerPoint — 650K searches/month
📋 How to Build — PDF to PowerPoint
- 1Add to requirements.txt:
python-pptx. - 2Image-based approach (best quality): Convert each PDF page to high-res image (PyMuPDF Matrix(2,2)), insert as full-slide background:
from pptx import Presentation; from pptx.util import Inches; prs = Presentation(); slide = prs.slides.add_slide(prs.slide_layouts[6]); slide.shapes.add_picture(img, 0, 0, width=prs.slide_width); prs.save(pptx_path) - 3Set 16:9 dimensions:
prs.slide_width = Inches(13.33); prs.slide_height = Inches(7.5). Slides look pixel-perfect — exactly what 90% of users need. Total build time: ~2 hours.
OCR — Scanned PDF to Searchable Text — 550K searches/month
📋 How to Build — OCR Tool
- 1Dockerfile: Add
RUN apt-get install -y tesseract-ocr tesseract-ocr-eng tesseract-ocr-hin(eng = English, hin = Hindi — big win for Indian users). - 2Add to requirements.txt:
pytesseract. - 3Process: Convert each PDF page to image (PyMuPDF) → run OCR:
import pytesseract; text = pytesseract.image_to_string(Image.open(page_img), lang='eng')→ compile all pages. - 4Output options: plain .txt file, or embed text as invisible searchable layer back into the original PDF (best option — preserves scanned look but makes it searchable).
- 5Let user select language. Hindi OCR for Indian users has near-zero competition. Total build time: ~3 hours.
AI Image Upscaler — 400K searches/month
📋 How to Build — AI Image Upscaler
- 1Add to requirements.txt:
realesrgan. ~65MB model, CPU-compatible — no GPU needed on Railway. - 2Backend:
from realesrgan import RealESRGANer; import cv2; upsampler = RealESRGANer(scale=2, model_path='RealESRGAN_x2plus.pth'); output, _ = upsampler.enhance(cv2.imread(input_path)); cv2.imwrite(output_path, output) - 3Free: 2× upscaling. PRO: 4× upscaling. Show before/after with zoom. CPU inference takes 10–30 seconds — always show a progress spinner. Total build time: ~3 hours.
💎 Phase 4 — PRO Conversion Features Weeks 4–6 · Revenue Drivers
Batch PDF Operations (Free: 3 files, PRO: unlimited)
📋 How to Build — Batch Processing
- 1On existing tool endpoints, check file count:
if len(files) > 3 and not user.is_pro: raise HTTPException(403, "Batch processing beyond 3 files requires PRO") - 2Process each file through existing single-file logic in a loop. Return all results as ZIP:
import zipfile; with zipfile.ZipFile(zip_path, 'w') as zf: [zf.write(f) for f in output_files] - 3Frontend: Change file input to accept multiple files (
multipleattribute). Show file list with individual progress bars. Counter: "3/3 files (Free — Upgrade for more)" or "3/∞ (PRO)". - 4Show upgrade banner immediately when free user selects their 4th file — don't wait for them to submit. Total build time: ~3 hours across all tools.
Tool History Dashboard (last 10 operations)
📋 How to Build — Tool History
- 1Your ToolUsage table already exists. Confirm columns:
tool_slug,original_filename,output_filename,file_size_kb,status,created_at. - 2In each tool endpoint, after success:
db.add(ToolUsage(user_id=user.id, tool_slug="pdf-compress", original_filename=file.filename, status="success")); db.commit() - 3Frontend: Add "Recent Activity" tab to user dashboard. Table: Date | Tool Used | File Name | Re-download (if file still exists within 24h).
- 4Free: last 3 operations, 3-day history. PRO: last 50 operations, 30-day history. The gap drives upgrades from power users who process many files daily. Total build time: ~3 hours.
Saved Presets (JSON in user_preferences table)
📋 How to Build — Saved Presets
- 1Add JSONB column:
ALTER TABLE users ADD COLUMN preferences JSONB DEFAULT '{}'; - 2On each tool page, show "Save as preset" button (PRO only). Saves current settings:
{"compression_quality": 75, "watermark_text": "DRAFT", "output_format": "pdf"}keyed by tool slug. - 3When PRO user returns to the tool, auto-load preset and pre-fill all settings. Makes the tool feel personal and irreplaceable.
- 4Users with saved presets are far less likely to switch to a competitor — they'd lose their custom settings. This is a churn-reduction feature disguised as convenience. Total build time: ~2 hours.
Video Trim — 350K searches/month
📋 How to Build — Video Trim
- 1ffmpeg command:
ffmpeg -ss 00:00:10 -to 00:00:30 -i input.mp4 -c copy output.mp4— trims from 10s to 30s.-c copy= no re-encoding = instant, lossless cut. - 2Frontend: Show a horizontal timeline bar. User drags left handle (start time) and right handle (end time). Show timecodes in real time (00:10 — 00:30).
- 3Add HTML5 video preview so user can watch the selected clip before trimming. On play, video jumps to start time automatically.
- 4Total build time: ~3 hours including timeline UI.
Video Watermark — Strong PRO conversion
📋 How to Build — Video Watermark
- 1Image / logo watermark:
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4— places logo in bottom-right corner, 10px from edges. Strong PRO conversion for watermark feature especially. - 2Text watermark:
ffmpeg -i input.mp4 -vf "drawtext=text='CONFIDENTIAL':fontsize=40:fontcolor=white@0.5:x=(w-text_w)/2:y=(h-text_h)/2" output.mp4 - 3Watermark positions: Top-left (
overlay=10:10), Top-right (W-w-10:10), Bottom-left (10:H-h-10), Bottom-right (W-w-10:H-h-10), Centre ((W-w)/2:(H-h)/2). - 4Free tier: fixed centre position, default opacity 50%. PRO: custom position picker, adjustable opacity slider, custom font/colour for text watermark.
- 5Total build time: ~2.5 hours.
Sign PDF (typed + image signature) — 900K searches/month
📋 How to Build — Sign PDF
- 1Option A — Typed signature: User types their name, picks a cursive font. Frontend renders on HTML5 canvas, exports as transparent PNG. Backend overlays on PDF:
page.insert_image(rect, filename=sig_png_path)(PyMuPDF). - 2Option B — Drawn signature: Use
react-signature-canvasnpm (free). User draws with mouse/finger on canvas → exports PNG → same backend overlay process. - 3Option C — Image upload: User uploads scanned signature. Use rembg to remove white background → overlay transparently on PDF at user-chosen position.
- 4Let user click on a PDF page preview to set signature position. Drag handles to resize. Free: 1 placement. PRO: multiple + save signature for reuse.
- 5Total build time: ~5 hours.
PDF Compare (show differences between two versions)
📋 How to Build — PDF Compare
- 1Extract text from both PDFs with PyMuPDF. Use Python difflib:
import difflib; diff = list(difflib.unified_diff(text1.splitlines(), text2.splitlines(), lineterm='')) - 2Display as side-by-side columns. Added lines = green highlight, removed lines = red highlight, unchanged = white. Page-by-page breakdown.
- 3Summary at top: "12 additions, 5 deletions across 3 pages." Changed page numbers as clickable jump links.
- 4Primary use: contract review (lawyer checking v1 vs v2). Very high PRO conversion. Total build time: ~3 hours.
PDF Annotate (highlight, comment, underline, draw)
📋 How to Build — PDF Annotate
- 1PyMuPDF full annotation support: Highlight:
page.add_highlight_annot(rect). Underline:page.add_underline_annot(rect). Comment:page.add_text_annot(point, "comment"). - 2Frontend: Render PDF pages as images. Overlay interactive canvas on top. User selects annotation tool (highlight/underline/comment/draw), interacts with canvas, sends annotation coordinates to backend.
- 3Backend applies annotations via PyMuPDF and returns the annotated PDF for download. Consider making this PRO-only — it's a very sticky feature that reduces churn.
- 4Total build time: ~5 hours (complex frontend canvas work).
PDF Redact — Black out sensitive text (Legal / HR / Government)
📋 How to Build — PDF Redact
- 1PyMuPDF redaction API properly removes the underlying text (unlike drawing a black box, which is a common security mistake):
page.add_redact_annot(rect, fill=(0,0,0)); page.apply_redactions() - 2Frontend: Render PDF as canvas. User draws black rectangles over sensitive areas. Send rectangle coordinates to backend for proper redaction.
- 3"Search and Redact" feature: User types a word/phrase → backend finds all instances → redacts them all. Very powerful for legal discovery work.
- 4Always warn: "⚠️ Redaction permanently removes content and cannot be undone." Total build time: ~3 hours.
🧑💻 Phase 5 — Developer & Power User Revenue Weeks 7–10
Developer API with API key auth
📋 How to Build — Developer API
- 1Your ApiKeys table and page already exist. Add a FastAPI dependency to check keys on endpoints:
async def verify_api_key(x_api_key: str = Header(...)): key = db.query(ApiKey).filter_by(key=x_api_key, is_active=True).first(); if not key: raise HTTPException(401) - 2Add dependency to tool endpoints:
@app.post("/api/v1/pdf/compress") async def api_compress(file: UploadFile, key=Depends(verify_api_key)): - 3Track usage per key. Return usage in response headers:
X-Usage-Count: 142,X-Usage-Limit: 1000. - 4Total build time: ~3 hours to wire up all major endpoints.
Per-call billing via Razorpay
📋 How to Build — API Billing
- 1Pricing tiers: Free = 100 calls/month, Starter = ₹499/month for 2,000 calls, Pro = ₹999/month for 10,000 calls. Developers budget API costs separately from personal expenses — very reliable payment.
- 2Add
monthly_api_callscounter to ApiKeys table. Increment on every successful API call. Reset on 1st of each month via a cron job. - 3When free limit (100 calls) is hit, return HTTP 429:
{"error": "Monthly API limit reached", "upgrade_url": "https://documateo.com/pricing#api"} - 4Create an API-specific section on /pricing. Developers look for this explicitly. Also create a /developers page (see next item). Total build time: ~4 hours.
API Documentation page at /developers
📋 How to Build — API Docs Page
- 1FastAPI auto-generates Swagger docs at
/docsalready. But create a nicer custom page at/developersthat people actually share and bookmark. - 2For each endpoint include: Authentication method (API key in X-API-Key header), Request format (multipart/form-data), Response format (JSON + file), Code examples in Python, JavaScript, and cURL.
- 3Example cURL:
curl -X POST https://api.documateo.com/api/v1/pdf/compress -H "X-API-Key: your_key" -F "file=@doc.pdf" -o compressed.pdf - 4Add a prominent "Get Free API Key" button. Frictionless signup — email only, no credit card needed. Total build time: ~3 hours.
Tool Pipeline / Chain Operations (Compress → Watermark → Protect)
📋 How to Build — Tool Pipeline
- 1Concept: User uploads one file, selects a sequence of operations to run in order (Compress → Add Watermark → Password Protect). One upload, one download, all steps applied.
- 2Backend:
POST /api/pipelineaccepts file + JSON steps array:[{"tool": "compress", "quality": 70}, {"tool": "watermark", "text": "CONFIDENTIAL"}, {"tool": "protect", "password": "1234"}]. Apply each step sequentially, feeding output of one into the next. - 3Frontend: Visual pipeline builder — user drags tool blocks into a sequence. Show estimated output file size after each step.
- 4Free: max 1 step (same as current single tools). PRO: up to 5 steps in sequence. This is the most powerful upgrade argument you have. Total build time: ~5 hours.
PDF Translate — iLovePDF AI feature (Future Goal)
📋 How to Build — PDF Translate
- 1Extract text from PDF with PyMuPDF. Send to translation API. DeepL API: 500,000 chars/month free. Google Translate API: $20 per 1M chars (pay per use).
- 2Simple approach: translate extracted text, deliver as plain .docx or .txt. Advanced: preserve PDF layout by translating text blocks and re-inserting at same coordinates via PyMuPDF.
- 3Priority language pairs: English ↔ Hindi, English ↔ Spanish, English ↔ French, English ↔ Arabic. These cover the majority of global demand.
- 4Free: 1 page. PRO: full document. Strong international PRO conversion. Total build time: ~4 hours.
🔒 Security
Security protects your users, your business, and your SEO ranking. Google penalises hacked sites. Tick each item off as you complete it.
🔒 Why Security Matters (Beginner Explanation)
Security isn't just about protecting data — it directly affects your income. A hacked website loses its Google ranking instantly. Users who feel unsafe don't return. AdSense can ban you if malicious code appears on your site. Fix these once and you're protected for years.
✅ Already Completed
These are done — tick them to reflect your real progress
Googlebot Whitelist — Fixed ✅
Cloudflare CDN — Active ✅
Security Headers — Grade A on securityheaders.com ✅
SSL Full (strict) + Always HTTPS enabled ✅
🔴 Still To Do — Critical
These are your remaining security tasks — check off as you complete them
File Upload Validation — Prevent Malicious File Uploads
📋 Guide — Server-Side File Validation
⚠️ Attackers can rename a PHP script as "report.pdf" and upload it. Server-side validation checks the actual file contents, not just the filename.
- 1Add to requirements.txt:
python-magicthen redeploy on Railway. - 2In your FastAPI upload handler, add:
import magic→ read first 2048 bytes → check MIME type against allowlist:["application/pdf", "image/jpeg", "image/png", "image/webp", "video/mp4"]→ reject anything else with HTTP 400. - 3Never store files with their original filename. Use
uuid.uuid4()to generate a random name — prevents path traversal attacks. - 4Store uploads in a temp directory that is NOT web-accessible. Only serve the processed output, never the raw upload.
- 5Test: try uploading a .txt file renamed as .pdf — should get a 400 error.
Enable 2FA on all accounts (Cloudflare, Railway, GitHub, Google, Razorpay)
📋 Guide — Enable 2FA on All Accounts
- 1Cloudflare: dash.cloudflare.com → My Profile (top right) → Authentication → Enable Two-Factor Authentication.
- 2GitHub: github.com → Settings → Password and authentication → Two-factor authentication → Enable.
- 3Railway: railway.app → Account Settings → Security → Two-Factor Authentication.
- 4Google (covers GA4, GSC, AdSense): myaccount.google.com → Security → 2-Step Verification → Turn on.
- 5Razorpay: dashboard.razorpay.com → Settings → Profile → Two-Factor Authentication.
- 6Use Microsoft Authenticator (already on your phone) for all of these — scan the QR code shown during setup for each account.
- 7Save the backup/recovery codes somewhere safe — print them or store in a password manager like Bitwarden (free).
Check GitHub repo for exposed secrets / API keys
📋 Guide — Scanning for Exposed Secrets
- 1Check your
.gitignore— must include:.env,.env.local,.env.production. - 2In your GitHub repo, use the search bar to search for "RAZORPAY", "SECRET", "PASSWORD". If any appear in actual code files — that's a problem.
- 3For full history scan:
pip install trufflehog→trufflehog git https://github.com/yourusername/yourrepo - 4If any secrets found in history: immediately rotate those keys (new Razorpay keys, etc.) then purge the git history.
- 5Going forward: all secrets in Railway's Environment Variables panel only — never in code.
Automatic file deletion — delete uploads after processing
📋 Guide — Auto-Delete Uploaded Files
⚠️ Keeping user files on your server longer than needed creates GDPR risk and wastes Railway storage. Delete immediately after sending the processed file back to the user.
- 1In each FastAPI endpoint, after sending the response, delete both the input and output files:
import os; os.remove(input_path); os.remove(output_path) - 2Add a background cleanup task using FastAPI's
BackgroundTasks— schedules deletion after the response is sent so it doesn't slow down the user. - 3Also add a fallback hourly sweep: using Python's
apschedulerlibrary, run a job every hour that deletes any files in /tmp older than 60 minutes.
Enable Cloudflare Bot Fight Mode + WAF managed ruleset
📋 Guide — Cloudflare Bot & WAF Setup
- 1Cloudflare dashboard → documateo.com → Security → Bots → Bot Fight Mode → toggle ON.
- 2Security → WAF → Managed Rules → enable the Cloudflare Managed Ruleset (free tier includes this).
- 3Security → DDoS → HTTP DDoS attack protection → set to High.
Run npm audit and fix critical/high vulnerabilities
📋 Guide — npm audit
- 1In your React project folder terminal:
npm audit— shows all vulnerabilities by severity. - 2Run
npm audit fix— auto-fixes most issues. - 3For remaining issues:
npm audit fix --force— then test your app still works. - 4Also run on backend:
pip install safety→safety check -r requirements.txt - 5Enable Dependabot on GitHub: repo → Settings → Code security → enable Dependabot alerts. It will auto-PR future fixes.
⚖️ Legal & Site Safety
Everything you must do to keep Documateo legally protected, secure from hackers, and reliably online. Tick these off one by one — most are free and take under 30 minutes.
🛡️ Why This Matters (Beginner Explanation)
Running a website without proper legal pages, security, and monitoring is like opening a shop without a lock on the door. Google can penalise you, AdSense can ban you, hackers can exploit you, and lawyers can come after you — all from things that take less than an hour to fix. Work through each section below in priority order.
⚖️ Section 1 — Legal Pages Do First
Required Legal Pages
Install a Cookie Consent Banner (CookieYes or Cookiebot)
📋 Step-by-Step — Cookie Consent Banner Setup
⚠️ Why is this CRITICAL? EU law (GDPR + ePrivacy Directive) says you cannot load Google Analytics or AdSense cookies UNTIL the user actively clicks "Accept". Having a Cookie Policy page alone is NOT enough — you need a popup banner that fires before any tracking starts. Google AdSense also now requires a CMP (Consent Management Platform) for EU traffic. Skip this and your AdSense account can be suspended.
- 1Go to cookieyes.com (free plan covers 1 website, up to 25,000 monthly sessions). Click "Get Started Free".
- 2Enter your website URL:
https://documateo.com. CookieYes will scan your site and detect all cookies automatically (including GA4 and AdSense cookies). - 3Choose a banner style — select a simple banner that appears at the bottom of the page. Keep it clean. You need: Accept button + Reject button + Preferences button.
- 4CookieYes gives you a small JavaScript snippet. Copy it.
- 5In your React project, open
public/index.html. Paste the CookieYes script tag inside the<head>section — paste it BEFORE your Google Analytics and AdSense scripts. - 6Deploy your site. Open it in a private/incognito browser tab — you should see the cookie banner appear at the bottom.
- 7Go back to CookieYes dashboard → Settings → Integrations → connect it to Google Analytics. This makes GA4 only load after the user consents.
- 8Alternative options if CookieYes doesn't suit you: Cookiebot.com (free up to 100 pages) or Termly.io (free plan available).
💡 Once CookieYes is live, go back to your Google AdSense application and confirm you have a CMP installed. This is one of the checkboxes in the AdSense approval flow for EU compliance.
Register a DMCA Agent with the US Copyright Office
📋 Step-by-Step — DMCA Agent Registration
⚠️ Why do you need this? Users upload files to your platform. What if someone uploads a copyrighted PDF — a textbook, a movie script, a paid report? Without a registered DMCA agent, YOU can be held legally responsible. With a registered agent and a DMCA page on your site, you get "Safe Harbour" — you are legally protected as long as you act on takedown requests. This is how YouTube, Google Drive, Dropbox all protect themselves. The fee is $6 total, not per year.
- 1Go to dmca.copyright.gov/osp (this is the official US Copyright Office website).
- 2Click "Create an account" — use your personal name or ARWebTools as the entity name.
- 3Click "Designate a New Agent" → fill in: Service Provider Name =
ARWebTools / Documateo, Website URL =https://documateo.com, Agent Name = your full name, Agent Email =[email protected]. - 4Pay the $6 fee by credit card. You receive a registration number — save this.
- 5Create a page on your website at
/dmcawith text like: "To report copyright infringement, contact us at [email protected] with the subject line DMCA Takedown. Include: (1) the copyrighted work being infringed, (2) the URL where infringing content appears, (3) your contact information and a statement that you are the copyright owner or authorised agent." - 6Add a link to your /dmca page in the website footer.
- 7Re-register every 3 years (the registration expires). Set a reminder in your calendar for 3 years from today.
💡 This registration costs $6 total and protects you from potentially massive copyright lawsuits. It's one of the best returns on investment in tech law. Most small website owners skip this and face huge risk.
Add clear Refund Policy to the Pricing page
📋 Step-by-Step — Writing Your Refund Policy
⚠️ Why is this important? Razorpay and Stripe can freeze your account if you receive too many chargebacks (disputes where users say "I never agreed to this charge"). A clearly visible refund policy reduces chargebacks because users know what to expect. Also, Indian consumer protection laws require clear refund terms for digital services.
- 1On your Pricing page, add a section titled "Refund Policy".
- 2Recommended text: "If you are not satisfied with your PRO subscription, you may request a full refund within 7 days of your initial purchase by contacting [email protected]. Refunds are not available after 7 days or for renewed subscription periods. To request a refund, email us with your order ID and reason."
- 3Also add this text near the "Subscribe" button: "7-day money-back guarantee. Cancel anytime." — this builds trust and actually increases conversions.
- 4Link to this refund policy from your Terms & Conditions page (Section 6 — Payments).
- 5In your Razorpay dashboard → Settings → Checkout Settings → enable "Show Refund Policy" and paste a short version of your policy there too.
Pin jurisdiction/governing law in your Terms & Conditions
📋 Guide — Setting Your Governing Law Clause
⚠️ Why does this matter? Your Terms currently say "applicable laws" without naming a country or state. This is legally weak — in any dispute, neither party knows which courts apply. Pin it to where ARWebTools is registered. This makes your Terms enforceable.
- 1Decide where ARWebTools is registered or operating from (e.g., Maharashtra, India).
- 2In your Terms.jsx, update Section 14 (Governing Law) to read: "These Terms shall be governed by and construed in accordance with the laws of India, with the courts of [your city, e.g. Mumbai] having exclusive jurisdiction over any disputes."
- 3Also add: "Nothing in this clause prevents either party from seeking urgent injunctive relief in any court of competent jurisdiction."
- 4Deploy the updated Terms.jsx. This change takes 5 minutes but makes your legal standing significantly stronger.
💡 If ARWebTools is not formally registered, now is a good time to consider registering as a Sole Proprietorship or OPC (One Person Company) in India. This takes 1-2 weeks and costs ₹3,000-₹8,000 via a CA, and gives your business a proper legal identity.
Create /dmca page on your website
📋 Guide — Creating the DMCA Page
- 1Create a new React page at route
/dmcain your project. - 2Title it "DMCA & Copyright Policy".
- 3Include: (a) a statement that you respect intellectual property rights, (b) how to submit a takedown notice (email, required info), (c) counter-notice process, (d) your DMCA agent registration number from the Copyright Office.
- 4Add a link to /dmca in the website footer alongside Privacy Policy and Terms.
- 5Add
<meta name="robots" content="noindex">to this page — it doesn't need to rank in Google.
Verify your updated Privacy Policy, Terms, Cookies & Security pages are live
📋 Checklist — Verify All Policy Pages
- 1Visit
https://documateo.com/privacy-policy— confirm it mentions Google Analytics, Google AdSense, Log Data, cookies, third-party links, and international data transfers. - 2Visit
https://documateo.com/cookies— confirm it has a cookie table listing _ga, _gid, IDE cookies with their durations, and opt-out links. - 3Visit
https://documateo.com/terms— confirm it mentions age eligibility (13+), advertising disclosure, and third-party links disclaimer. - 4Visit
https://documateo.com/security— confirm it mentions log data, access controls, and the security reporting email. - 5Check your footer links — confirm all four pages are linked in the footer of every page.
- 6Check the "Last updated" date on each page renders correctly (should show a real date, not JavaScript code).
🔒 Section 2 — Security Hardening Do This Week
Security Headers — Free, 5-Minute Fix
Add all Security Headers via Cloudflare Transform Rules
📋 Step-by-Step — Adding Security Headers in Cloudflare
⚠️ What are security headers? They are invisible instructions your website sends to the browser that say "don't allow X dangerous behaviour". Without them, hackers can inject scripts into your pages (XSS attacks), frame your site inside theirs (clickjacking), or trick browsers into running dangerous files. All free to add via Cloudflare in under 10 minutes.
- 1First, test your current score: go to securityheaders.com → enter
https://documateo.com→ click Scan. Note your grade (probably D or F right now). Screenshot it for comparison later. - 2Log into dash.cloudflare.com → select documateo.com → click "Rules" in the left sidebar → click "Transform Rules".
- 3Click "Create Transform Rule" → choose "Modify Response Header".
- 4Name the rule:
Security Headers. Under "When incoming requests match", select "All incoming requests". - 5Under "Then" → "Modify response header" → Add these one by one (click "Add" for each):
Header name:X-Frame-Options→ Value:SAMEORIGIN
Header name:X-Content-Type-Options→ Value:nosniff
Header name:Referrer-Policy→ Value:strict-origin-when-cross-origin
Header name:Permissions-Policy→ Value:geolocation=(), microphone=(), camera=()
Header name:X-XSS-Protection→ Value:1; mode=block - 6Click Save. Cloudflare will now add these headers to every response from your site.
- 7Wait 2 minutes → go back to securityheaders.com → scan again → your grade should now be A or B. Screenshot the improvement.
- 8Note: Do NOT add
Content-Security-Policyright now — it requires careful configuration specific to your app and can break AdSense ads if misconfigured. Add it later when you're comfortable.
💡 This single Cloudflare rule improves your security grade from F to A. Takes 10 minutes. Protects millions of potential users. One of the best 10-minute investments you can make for your website.
Verify SSL certificate auto-renewal is active
📋 Guide — Checking SSL Certificate Auto-Renewal
- 1In Cloudflare dashboard → select documateo.com → click SSL/TLS in the left sidebar.
- 2Click "Edge Certificates" → you should see a certificate listed with a status of "Active".
- 3Check the expiry date — Cloudflare automatically renews these. If it says "Active" and was issued by Cloudflare, you're protected.
- 4Also check: SSL/TLS → Overview → ensure the mode is set to "Full (strict)" — not "Flexible". Flexible mode has a known security vulnerability.
- 5Enable "Always Use HTTPS" toggle (also on this page) — this forces all http:// traffic to redirect to https:// automatically.
- 6Enable "Automatic HTTPS Rewrites" — this fixes mixed-content warnings where some resources load over http inside an https page.
File Upload & API Protection
Implement server-side file upload validation in FastAPI
📋 Guide — Server-Side File Validation in FastAPI
⚠️ What is the risk? An attacker can rename a PHP script as "report.pdf" and upload it. If your server just trusts the file extension, it might execute that script — giving the attacker full control of your server. Server-side validation checks the actual contents of the file, not just its name.
- 1Install the python-magic library: run
pip install python-magicin your Railway environment (add to requirements.txt). - 2In your FastAPI upload handler, add this validation:
import magicfile_bytes = await file.read(2048)mime = magic.from_buffer(file_bytes, mime=True)allowed = ["application/pdf", "image/jpeg", "image/png", "image/webp", "video/mp4"]if mime not in allowed: raise HTTPException(400, "Invalid file type") - 3Also enforce a maximum file size on the server side (not just the frontend): check
file.sizebefore processing and reject files over your limit (e.g. 50MB for free users). - 4Never store uploaded files with their original filename. Generate a random UUID filename:
import uuid; safe_name = str(uuid.uuid4()) + ".pdf". This prevents path traversal attacks. - 5Store uploaded files in a temp directory that is NOT web-accessible (not in your public static folder). Only the processed output should ever be downloadable.
💡 This is the most important technical security fix for a file-processing site. Once implemented, test it by trying to upload a .txt file renamed as .pdf — your server should reject it with a 400 error.
Add rate limiting to all FastAPI upload endpoints (slowapi)
📋 Guide — Adding Rate Limiting with slowapi
⚠️ What happens without rate limiting? A single script can make 10,000 requests to your /api/compress endpoint in 60 seconds, exhausting your Railway server resources and running up costs. Rate limiting caps how many requests one IP address can make per minute.
- 1Add to your requirements.txt:
slowapiandlimits. - 2In your FastAPI main.py:
from slowapi import Limiter, _rate_limit_exceeded_handlerfrom slowapi.util import get_remote_addressfrom slowapi.errors import RateLimitExceededlimiter = Limiter(key_func=get_remote_address)app.state.limiter = limiterapp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) - 3Add the rate limit decorator to each upload endpoint:
@app.post("/api/compress")@limiter.limit("10/minute")async def compress(request: Request, file: UploadFile = File(...)): - 4Recommended limits: Free upload endpoints =
10/minute. General API =60/minute. Health endpoint =120/minute. PRO authenticated users can have higher limits. - 5Test it: use a tool like curl to hit your endpoint 15 times quickly — after 10 requests/minute you should get a 429 "Too Many Requests" response.
Check for exposed environment variables / secrets in your GitHub repo
📋 Guide — Scanning for Exposed Secrets
⚠️ Why is this critical? If you ever accidentally committed a .env file, API key, Razorpay secret, or database password to GitHub — even if you deleted it later — bots scan GitHub 24/7 and find these within minutes. Exposed Razorpay secrets can drain your account. Exposed database credentials give attackers full access to user data.
- 1Check your
.gitignorefile right now. Make sure it includes:.env,.env.local,.env.production,*.key,secrets.json. - 2Go to your GitHub repo → search for "RAZORPAY" or "SECRET" or "PASSWORD" in the repo search bar. If any results appear in actual code files (not .gitignore), that's a problem.
- 3For a thorough scan, install truffleHog:
pip install trufflehog→ then runtrufflehog git https://github.com/yourusername/yourrepo. It scans your entire git history for secrets. - 4If any secrets are found in history: immediately rotate/regenerate those keys (new Razorpay keys, new API keys etc.), then use git history rewriting tools or contact GitHub support to purge the history.
- 5Going forward: All secrets go in Railway's Environment Variables panel (not in code). In local development, keep them in a
.envfile that is in .gitignore. Never hardcode any key in source code.
Run npm audit and fix high/critical vulnerabilities
📋 Guide — Running npm audit
- 1Open a terminal in your React project folder. Run:
npm audit. This checks all your installed packages against a database of known vulnerabilities. - 2The output will show: Critical, High, Medium, Low vulnerabilities. Focus only on Critical and High first.
- 3Run
npm audit fix— this automatically fixes most issues by updating packages to safe versions. - 4For issues that
npm audit fixcan't auto-fix, runnpm audit fix --force— but carefully check if this breaks anything in your app after running it. - 5Set up Dependabot on GitHub (free): go to your GitHub repo → Settings → Code security → Enable Dependabot alerts + Dependabot security updates. GitHub will automatically open pull requests when vulnerable packages are detected in future.
- 6Do the same for your Python backend: run
pip install safety→ thensafety check -r requirements.txtto scan Python packages too.
💡 Run npm audit every month as part of your monthly review. It takes 2 minutes and catches vulnerabilities that attackers actively exploit.
Admin & Access Protection
Secure your admin panel — ensure it's not at /admin or /dashboard (common scan targets)
📋 Guide — Securing Your Admin Area
⚠️ What is the risk? Automated bots constantly scan every website for /admin, /dashboard, /wp-admin, /login etc. If they find your admin page and it's at one of these common paths with weak authentication, brute-force attacks are trivial. Move it to a non-obvious path and add proper authentication.
- 1If you have an admin panel, move it to a non-obvious URL path (e.g.,
/control-4729or similar — keep it secret). Do not use /admin, /dashboard, /manage. - 2Add a
<meta name="robots" content="noindex, nofollow">tag to your admin/dashboard page — this prevents it from being indexed. - 3In Cloudflare → Security → WAF (Web Application Firewall) → create a rule that blocks access to your admin path from all countries except India (or wherever you work from). This is free on Cloudflare's free tier.
- 4Enable Cloudflare's Bot Fight Mode: Security → Bots → Bot Fight Mode → Enable. This blocks known malicious bots automatically.
- 5Use a strong password for your Railway, Cloudflare, and Google accounts. Enable 2-Factor Authentication (2FA) on all three — this is the single most effective anti-hacking measure. Use Google Authenticator or Authy app.
🏗️ Section 3 — Site Durability & Reliability This Week
Monitoring — Know Before Your Users Do
Set up UptimeRobot — get alerted when your site goes down
📋 Guide — Setting Up UptimeRobot
⚠️ What is this? UptimeRobot visits your website every 5 minutes to check if it's online. If it's down (server crashed, DNS issue, Railway outage), it immediately emails you. Without this, you might not know your site is down for hours — losing visitors, AdSense revenue, and trust. Free plan monitors up to 50 websites.
- 1Go to uptimerobot.com → Sign up free → log in to dashboard.
- 2Click "Add New Monitor". Set: Monitor Type =
HTTP(s), Friendly Name =Documateo Frontend, URL =https://documateo.com, Monitoring Interval =5 minutes. Click Save. - 3Add a second monitor for your backend: Friendly Name =
Documateo API, URL =https://[your-railway-url]/health. - 4Make sure your FastAPI has a
/healthendpoint:@app.get("/health") async def health(): return {"status": "ok"}. - 5In UptimeRobot → Alert Contacts → add your email address. You'll now get an email within 5 minutes of any outage.
- 6Bonus: The backend monitor also prevents Railway cold starts by pinging your server every 5 minutes (replaces the separate keep-alive task in the Apps section).
💡 This is free and takes 5 minutes. It means you will always know about outages before your users tweet about them. Absolutely essential for any public website.
Set up Sentry error monitoring (free tier)
📋 Guide — Setting Up Sentry
⚠️ What is Sentry? When your website has an error — like a PDF compression tool crashes for a specific file type — Sentry captures it silently and sends you a detailed report: what broke, which line of code, which browser, which file type triggered it. Without Sentry, these errors are invisible. You only find out when a user complains.
- 1Go to sentry.io → Sign up free (free plan: 5,000 errors/month, 1 project). Create a new project → select React.
- 2Sentry gives you a DSN (a URL that looks like
https://[email protected]/12345). Copy it. - 3In your React project:
npm install @sentry/react. - 4In your
src/main.jsxorsrc/index.js(your app entry point), add:import * as Sentry from "@sentry/react";Sentry.init({ dsn: "YOUR_DSN_HERE", tracesSampleRate: 0.1 }); - 5Deploy. Now go to your site and deliberately cause an error (e.g., visit a non-existent route) → check your Sentry dashboard → the error should appear within 30 seconds.
- 6Optional: also add Sentry to your FastAPI backend.
pip install sentry-sdk[fastapi]→ addsentry_sdk.init(dsn="YOUR_DSN")to your FastAPI main.py.
💡 Once Sentry is live, you'll often discover bugs that have been silently failing for weeks — things users hit but never bothered to report. Fixing these dramatically improves tool completion rates.
Backups — Don't Lose Everything
Verify all code is on GitHub with recent commits (your primary backup)
📋 Guide — Verifying Code Backup on GitHub
- 1Go to your GitHub repo → check the last commit date. It should be recent (within the last few days at most).
- 2Make sure your Railway FastAPI backend code is also in a GitHub repo — separate from your frontend repo. Both must be backed up.
- 3Confirm your repos are Private (not Public) on GitHub to protect your source code.
- 4Get in the habit: every time you make changes and test them, run:
git add . && git commit -m "description of change" && git push. This is your save button. - 5Check that your
.envfile is in.gitignore— it should never appear in your GitHub repo. Environment variables live in Railway's dashboard, not in code.
Enable 2-Factor Authentication on Railway, Cloudflare, GitHub, Google, and Razorpay
📋 Guide — Enabling 2FA on All Critical Accounts
⚠️ Why is 2FA so important? If someone steals your password (via phishing, data breach, or password reuse), 2FA stops them completely because they still need your phone. Without 2FA, one stolen password = attacker can delete your Railway server, redirect your Cloudflare DNS, drain your Razorpay account, or lock you out of Google AdSense.
- 1First, install Google Authenticator or Authy on your phone (free apps). These generate 6-digit codes every 30 seconds.
- 2Cloudflare: dash.cloudflare.com → top-right profile icon → My Profile → Authentication → Two-Factor Authentication → Enable → scan QR code with your authenticator app.
- 3GitHub: github.com → Settings → Password and authentication → Enable two-factor authentication → choose Authenticator App → scan QR code.
- 4Railway: railway.app → Account → Security → Enable 2FA.
- 5Google Account (covers Gmail, GA4, GSC, AdSense): myaccount.google.com → Security → 2-Step Verification → Get started.
- 6Razorpay: dashboard.razorpay.com → Settings → Profile → Two-Factor Authentication → Enable.
- 7Save your backup/recovery codes somewhere safe (printed or in a secure password manager like Bitwarden — also free). If you lose your phone, backup codes are how you get back in.
💡 After enabling 2FA on all accounts, your Documateo business is protected against the most common forms of account takeover. This takes 15 minutes and is arguably the most important security action on this entire list.
Performance & Load Testing
Enable Cloudflare Bot Fight Mode and WAF
📋 Guide — Cloudflare Bot Protection
- 1Cloudflare dashboard → select documateo.com → click Security in left sidebar → click Bots.
- 2Enable Bot Fight Mode toggle → this blocks known malicious bots from even reaching your server.
- 3Go to Security → WAF (Web Application Firewall) → enable the managed ruleset. This blocks common web attacks (SQL injection, XSS, etc.) before they hit your FastAPI.
- 4Go to Security → DDoS → ensure DDoS protection is set to "High". Cloudflare's free DDoS protection can absorb millions of requests per second.
Load test your upload endpoints before any marketing campaign or traffic spike
📋 Guide — Load Testing with loader.io
- 1Go to loader.io → Sign up free → verify your site by adding a verification file to your Cloudflare Pages deployment.
- 2Create a new test: Target URL = your most-used tool endpoint (e.g.,
/api/compress), Test type = Clients per test, Clients = ramp from 1 to 50 over 60 seconds. - 3Run the test. Watch the response times and error rates. If you start seeing errors above 20 concurrent users, your Railway server is at its limit.
- 4If response times exceed 5 seconds at 20 users, consider upgrading your Railway plan from the free tier to a paid tier before running any paid marketing campaigns.
- 5Do this test before: any Product Hunt launch, any paid ad campaign, any Reddit/social media post you expect to go viral.
📋 Quick Priority Summary
Do these in order. Most are free. Most take under 30 minutes. Together they protect you legally, technically, and commercially.
| # | Task | Time | Cost | Priority |
|---|---|---|---|---|
| 1 | Cookie Consent Banner (CookieYes) | 20 min | Free | CRITICAL |
| 2 | Enable 2FA on all accounts | 15 min | Free | CRITICAL |
| 3 | UptimeRobot monitoring | 5 min | Free | CRITICAL |
| 4 | Security Headers via Cloudflare | 10 min | Free | CRITICAL |
| 5 | Verify GitHub repo / code backed up | 5 min | Free | CRITICAL |
| 6 | SSL set to Full (strict) + Always HTTPS | 2 min | Free | CRITICAL |
| 7 | DMCA Agent registration | 30 min | $6 once | CRITICAL |
| 8 | Refund Policy on Pricing page | 15 min | Free | CRITICAL |
| 9 | File upload validation (FastAPI) | 45 min | Free | CRITICAL |
| 10 | Rate limiting (slowapi) | 30 min | Free | CRITICAL |
| 11 | Sentry error monitoring | 20 min | Free | HIGH |
| 12 | Cloudflare Bot Fight Mode + WAF | 2 min | Free | HIGH |
| 13 | Scan GitHub repo for exposed secrets | 10 min | Free | HIGH |
| 14 | npm audit + fix vulnerabilities | 10 min | Free | HIGH |
| 15 | Secure admin panel path + Cloudflare WAF rule | 15 min | Free | HIGH |
| 16 | Pin jurisdiction in Terms of Service | 5 min | Free | HIGH |
| 17 | Load test before traffic spikes | 20 min | Free | MEDIUM |
📡 Reachability & Fine-Tuning
Free actions to make Documateo easier to find, faster to load, and more trusted by Google and real users. No budget needed — just time.
💡 What Is "Reachability"?
Reachability means: can people find you, reach you, and trust you — across Google, social, directories, and performance benchmarks. Every item here is free. Together they compound over time to bring more organic traffic without spending on ads.
🔍 Section 1 — Google Presence High Impact
Make Google trust and understand your site better
Add structured data (Schema markup) to your tool pages
📋 Guide — Adding Schema Markup
⚠️ What is this? Schema markup is invisible code you add to your pages that tells Google exactly what your page is — "this is a software tool called PDF Compressor, it does X, it's free". Google uses this to show richer search results (star ratings, tool descriptions, breadcrumbs) which dramatically increases click-through rates.
- 1For each tool page, add a
SoftwareApplicationschema. In your React tool component, add inside the<head>(via react-helmet or your index.html):<script type="application/ld+json">{"@context":"https://schema.org","@type":"SoftwareApplication","name":"PDF Compressor","applicationCategory":"UtilitiesApplication","operatingSystem":"Web","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"description":"Compress PDF files online for free"}</script> - 2For your blog posts, add
Articleschema withdatePublished,author, andheadlinefields. - 3For your homepage, add
WebSiteschema with aSearchAction— this enables the Google sitelinks searchbox. - 4Test your schema at search.google.com/test/rich-results — paste your URL and see what Google detects.
- 5After deploying, go to GSC → Enhancements → you'll see rich result data appear within 2-4 weeks.
💡 This is one of the highest-leverage free SEO actions. Sites with schema markup get 20-30% higher click-through rates from the same Google ranking position.
Create and submit an XML sitemap to Google Search Console
📋 Guide — Sitemap Submission
- 1Check if your sitemap already exists: visit
https://documateo.com/sitemap.xmlin your browser. If it loads, you're good. If not, create one. - 2To create: use xml-sitemaps.com (free, crawls your site automatically) or manually create a sitemap.xml listing all your tool and blog URLs.
- 3Place sitemap.xml in your
public/folder so it's accessible at the root URL. - 4In GSC → Sitemaps → enter
sitemap.xml→ click Submit. GSC will now crawl all listed URLs. - 5Also add this line to your
public/robots.txt:Sitemap: https://documateo.com/sitemap.xml - 6Re-submit sitemap every time you add a significant batch of new pages (e.g. after adding 10+ new blog posts or tools).
Set up Google Business Profile (free listing)
📋 Guide — Google Business Profile
- 1Go to business.google.com → click "Manage now" → sign in with your Google account.
- 2Search for "ARWebTools" — it probably doesn't exist yet. Click "Add your business".
- 3Business name:
ARWebToolsorDocumateo. Category:Software CompanyorInternet Company. - 4Add your website URL, description, and support email. You don't need a physical address for online businesses.
- 5Verify ownership (usually via email or Google Search Console connection).
- 6Once live, when someone searches "Documateo" or "ARWebTools" on Google, your brand panel appears on the right. This significantly boosts trust.
⚡ Section 2 — Site Performance Google Ranks Fast Sites Higher
Core Web Vitals — Google's speed ranking signals
Run PageSpeed Insights and fix your Core Web Vitals score
📋 Guide — Improving PageSpeed Score
⚠️ Why does this matter for ranking? Google officially uses page speed as a ranking factor. A slow site (score below 50) ranks lower than a fast competitor even if your content is better. Most issues are fixable for free.
- 1Go to pagespeed.web.dev → enter
https://documateo.com→ run analysis. Focus on the Mobile score (harder to achieve, bigger ranking impact). - 2Fix: Largest Contentful Paint (LCP) — usually your hero image or logo. Make sure your logo is WebP format (not PNG/JPG) and add
loading="eager"to the hero image tag. - 3Fix: Cumulative Layout Shift (CLS) — add explicit
widthandheightattributes to all<img>tags. This prevents layout jumping as images load. - 4Fix: Unused JavaScript — in your React build, enable code splitting: use
React.lazy()andSuspensefor heavy tool components so they only load when needed. - 5Enable Cloudflare's speed features: Speed → Optimization → Auto Minify (enable JS, CSS, HTML) + Rocket Loader → ON. These are free and often add 10-15 points to your score.
- 6Enable Cloudflare Caching: Caching → Configuration → Browser Cache TTL = 4 hours. Caching Rule → Cache Everything for static assets.
💡 A score of 90+ on mobile puts you in the top 10% of websites globally. Each 10-point improvement measurably increases Google ranking positions for competitive keywords.
Add Open Graph meta tags to all pages (social sharing previews)
📋 Guide — Open Graph Tags
- 1In each page component, use react-helmet (or your existing helmet setup) to add these meta tags:
<meta property="og:title" content="PDF Compressor — Documateo" />
<meta property="og:description" content="Compress PDF files online free. No signup required." />
<meta property="og:image" content="https://documateo.com/og-image.png" />
<meta property="og:url" content="https://documateo.com/pdf/compress" />
<meta property="og:type" content="website" /> - 2Create one OG image (1200×630px) in Canva (free) — your logo + tagline on a clean background. Save as
og-image.pngin your public folder. - 3Also add Twitter card tags:
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="PDF Compressor — Documateo" /> - 4Test: go to opengraph.xyz → paste your URL → see exactly what preview appears when shared. Fix until it looks professional.
💡 Without OG tags, sharing your URL on WhatsApp shows a blank preview. With them, it shows a proper card with image, title, and description — dramatically increasing click-through when people share your tools.
📋 Section 3 — Free Directory Listings Backlinks + Traffic
Submit to free directories — each gives a backlink and potential users
Submit to Product Hunt
📋 Guide — Product Hunt Launch
⚠️ Product Hunt launches work best when planned. Don't just submit and hope. Build a small audience first (even 20 people who will upvote on launch day makes a huge difference).
- 1Create an account at producthunt.com — spend 1-2 weeks engaging with other launches first (upvote, comment). New accounts that launch immediately get less traction.
- 2Prepare your listing: name = "Documateo", tagline = "Free PDF, image & video tools — no signup, no ads, browser-only", upload 4-5 screenshots of your best tools.
- 3Schedule your launch for a Tuesday or Wednesday — these are the highest-traffic days. Launch at 12:01 AM PST (the daily leaderboard resets at midnight PST).
- 4Before launching, tell friends, WhatsApp contacts, LinkedIn connections to visit Product Hunt and upvote on launch day. Don't send direct links to the PH page before launch — it can get you disqualified.
- 5On launch day: be active in the comments — reply to every comment within 30 minutes. This signals engagement and boosts your ranking.
💡 A successful Product Hunt launch (top 5 of the day) can bring 500-2,000 visitors in 24 hours and gives you a permanent "Featured on Product Hunt" badge to display on your site.
Submit to free tool directories (backlinks + traffic)
📋 Guide — Free Directory Submissions
- 1AlternativeTo.net — submit Documateo as an alternative to iLovePDF, Smallpdf, Adobe Acrobat. Free. Each "alternative" listing drives people searching those tools to find you.
- 2SaaSHub.com — free SaaS directory. Submit at saashub.com/submit. Gives a dofollow backlink.
- 3Toolify.ai — directory of online tools. Free submission.
- 4There's An AI For That (theresanaiforthat.com) — if any of your tools use AI (background removal, etc.), submit here. Huge traffic source.
- 5Hacker News "Show HN" — post "Show HN: Documateo – free browser-based PDF/image/video tools" on news.ycombinator.com. Do this on a weekday morning US time. Even modest traction here drives quality developer traffic.
- 6Reddit — post in r/webtools, r/Entrepreneur, r/SideProject. Be genuine — explain what you built and why. Don't spam.
💡 Each directory submission takes 5-10 minutes and creates a permanent backlink. 10 backlinks from reputable directories = measurable improvement in Google rankings within 4-8 weeks.
Create a free Bing Webmaster Tools account and submit sitemap
📋 Guide — Bing Webmaster Tools
- 1Go to bing.com/webmasters → sign in with Microsoft account → Add your site:
https://documateo.com. - 2Verify ownership — easiest method: import from Google Search Console (one click if you're already verified in GSC).
- 3Submit your sitemap: Sitemaps → Submit sitemap →
https://documateo.com/sitemap.xml. - 4Use Bing's free "URL Inspection" tool to request indexing of your most important pages immediately.
💡 Bing also powers DuckDuckGo, Yahoo, and Microsoft Edge search. Getting indexed here adds meaningful traffic at zero cost — and competition is much lower than Google.
✨ Section 4 — UX Fine-Tuning Retention + Trust
Small changes that make users stay longer and come back
Add a favicon and app icons (PWA-ready)
📋 Guide — Favicon Setup
- 1Go to favicon.io (free) → generate a favicon from your logo or text → download the ZIP file.
- 2Place all generated files (favicon.ico, apple-touch-icon.png, android-chrome-*.png) in your
public/folder. - 3In
public/index.html, add in the<head>:
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> - 4Also update your
public/manifest.jsonwith your app name and icon paths — this enables "Add to Home Screen" on mobile browsers.
Add a 404 page with helpful links back to your tools
📋 Guide — Custom 404 Page
- 1In your React router, add a catch-all route:
<Route path="*" element={<NotFound />} />. - 2Create a
NotFound.jsxcomponent. Keep it friendly — "Oops, this page doesn't exist." with your logo and branding. - 3Add 3-4 links: "Go to PDF Tools", "Go to Image Tools", "Go Home". This recovers lost users instead of sending them away.
- 4Also create a
public/_redirectsfile (for Cloudflare Pages) with:/* /index.html 200— this ensures React Router handles all routes correctly.
Add a "Related Tools" section at the bottom of each tool page
📋 Guide — Related Tools Widget
- 1After the main tool output area, add a "You might also need:" section.
- 2PDF Compressor → suggest: PDF Merger, PDF Splitter, PDF to Image.
- 3Image Compressor → suggest: Image Resize, Background Remover, Image Converter.
- 4Display as simple card grid (2-4 tools, with icon + name + short description). Keep it clean.
- 5This doubles as internal linking — Google follows these links and discovers/re-crawls your other tool pages more frequently.
💡 Canva, iLovePDF, and every major tool site does this. Users who just compressed a PDF often immediately need to merge or protect it. Don't let them go to a competitor for the next step.
Add a visible email capture / newsletter signup (Brevo free)
📋 Guide — Email List Building
⚠️ Why does this matter? Google traffic can disappear overnight (algorithm update). An email list is traffic you own — no algorithm can take it away. Even 500 subscribers = a reliable base of users to announce new tools, promotions, or blog posts to.
- 1You already have Brevo set up. In Brevo → Forms → Create a subscription form. Keep it dead simple: just an email field + "Get notified of new tools" button.
- 2Embed the form in your site footer (visible on every page) and optionally as a subtle banner after a user successfully uses a tool ("Liked this tool? Get notified of new ones →").
- 3Offer a small incentive: "Subscribe and get a free PDF compression cheatsheet" — create a simple 1-page PDF tip sheet in Canva (takes 20 minutes, free).
- 4In Brevo, set up a simple welcome email: sent automatically when someone subscribes. Just say thank you + link to your most popular tools.
📊 GSC Page Indexing Tracker
Track which pages Google has indexed. Click any page to toggle its status. Save your progress when done.
📊 How to Check if a Page is Indexed (Step by Step)
1
Go to search.google.com/search-console → URL Inspection → paste a URL.
2
If it says "URL is on Google" → mark it as Indexed here (click the item below).
3
If it says "URL is not on Google" → click "Request Indexing" in GSC → mark as Pending here.
4
Do 10 pages per day. Come back tomorrow and check the ones you requested yesterday.
Indexing Status Overview
Indexed: 0
Pending: 0
🧩 Apps & Analytics Setup
The analytics and external tools you need to track growth, understand users, and earn money. Each has a setup guide.
Analytics Stack — Know Your Numbers
✓
Google Search Console (GSC)
✓
Google Analytics 4 (GA4)
Microsoft Clarity — Session recordings + heatmaps
📋 Clarity Setup Guide
- 1Go to clarity.microsoft.com → Sign in with Microsoft account → Add new project.
- 2Enter project name = Documateo, URL = https://documateo.com. Click Continue.
- 3Copy the JavaScript snippet. Paste into your site's
<head>tag (in public/index.html). - 4Deploy site. Data starts appearing within a few hours of receiving traffic.
- 5After 3 days: Watch 5 session recordings → note where users get confused. Check heatmaps on /pdf/compress and /image/remove-bg.
Set up GA4 conversion events for PRO upgrades + affiliate clicks
📋 Guide — Setting Up GA4 Conversion Tracking
⚠️ What is a "conversion event"? An event is something you track in GA4. A conversion event is a specific action you care about — like someone clicking "Upgrade to PRO" or clicking an affiliate link. Without tracking these, you're flying blind on what's earning money.
- 1In your React app, import GA4:
import ReactGA from 'react-ga4'. Initialize with your tracking ID. - 2Track PRO upgrade button clicks:
ReactGA.event({ category: 'Revenue', action: 'PRO Upgrade Click', label: 'trigger_type' }). - 3Track affiliate link clicks:
ReactGA.event({ category: 'Revenue', action: 'Affiliate Click', label: 'adobe_acrobat' }). - 4Track tool completions:
ReactGA.event({ category: 'Engagement', action: 'Tool Used', label: 'pdf_compress' }). - 5In GA4 dashboard: Admin → Events → Mark your revenue events as "Conversions". Then you can see daily conversion counts.
Hosting & Infrastructure
✓
Cloudflare Pages — Frontend hosting
Set up Railway uptime monitoring (avoid cold starts)
📋 Guide — Preventing Railway Cold Starts
⚠️ What is a cold start? Railway's free tier "sleeps" your server when there's no traffic for a while. When a user visits, they wait 15-30 seconds for the server to wake up. This kills conversions — users think the site is broken and leave.
- 1Go to uptimerobot.com — free tier lets you monitor 50 websites. Sign up free.
- 2Add a new monitor: Type = HTTP(s), URL = your Railway backend URL (e.g., https://documateo-api.railway.app/health), Interval = every 5 minutes.
- 3This pings your server every 5 minutes, keeping it "awake" so users never experience a cold start.
- 4Bonus: UptimeRobot also emails you if your site goes down — so you know about outages before your users complain.
- 5Make sure your FastAPI has a
/healthendpoint that just returns{"status": "ok"}. This is the endpoint UptimeRobot pings.
Payment & Email
✓
Razorpay — Payment gateway (INR subscriptions)
✓
Brevo — Email marketing (300 emails/day free)
₹ Revenue Model
How each rupee is earned. Multiple streams = safety. One stream underperforms, others cover it.
Revenue Forecast by Month
| Month | Est. Visitors | AdSense | Affiliates | PRO Subs | Total |
|---|---|---|---|---|---|
| 1 | 500–2,000 | ₹150–₹600 | ₹100–₹400 | ₹50–₹100 | ₹300–₹1,100 |
| 2 | 2,000–6,000 | ₹600–₹1,800 | ₹700–₹2,500 | ₹200–₹1,000 | ₹1,500–₹5,300 |
| 3 | 6,000–15,000 | ₹1,800–₹4,500 | ₹1,500–₹5,000 | ₹700–₹3,500 | ₹4,000–₹13,000 |
| 4 | 15,000–30,000 | ₹4,500–₹9,000 | ₹3,000–₹12,000 | ₹2,000–₹6,000 | ₹9,500–₹27,000 |
| 5 | 30,000–60,000 | ₹9,000–₹18,000 | ₹6,000–₹22,000 | ₹6,000–₹11,000 | ₹21,000–₹51,000 |
| 6 | 60,000–1,20,000 | ₹18,000–₹36,000 | ₹12,000–₹60,000 | ₹16,000–₹27,000 | ₹46,000–₹1,23,000 |
Assumptions: AdSense RPM ₹30–₹50 (Indian traffic). Affiliate 0.1–0.2% click-to-sale rate. PRO conversion 0.3–0.5% of visitors. All estimates assume AdSense + Ezoic from Month 3 (2-3× RPM boost).
Ad Revenue Upgrade Path
Now
Google AdSense
RPM: ₹30–₹50. Auto Ads for first 2 weeks. Manual optimization after.
10k sessions/mo
Ezoic
RPM: ₹80–₹150. AI-optimized ad placement. 2-3× revenue improvement overnight.
50k sessions/mo
Mediavine
RPM: ₹200–₹400. Premium publishers. Very high-quality ads. Application required.
100k sessions/mo
Raptive (AdThrive)
RPM: ₹400–₹800. Top tier. Invitation or application. Best RPM available.
Affiliate Income Roadmap
Month 1
Adobe Acrobat + Canva Pro
₹600–₹2,500/sale. Apply this week. 2-5 day approval. Highest priority.
Month 2
Grammarly + Notion (CJ Affiliate)
Grammarly pays per free signup. Notion pays per upgrade. Easy contextual fit.
Month 3+
ilovepdf competitors, Pdfgear, more
Expand affiliate portfolio as traffic grows. Higher traffic = easier approvals.
📋 Weekly Routine System
Consistency beats intensity. Do these small actions every week and you'll outgrow any competitor who works in bursts.
🗓️ Your Weekly Routine (Total: ~4 hours/week)
The secret to SEO growth isn't one big push — it's consistent small actions every week. Here's your sustainable weekly routine that compounds over time:
Monday (45 min)
📊 Check GA4 → note top pages, traffic trends
🔍 Check GSC → any new rankings? Errors?
💰 Check AdSense/Ezoic earnings from last week
📋 Request indexing for 10 pages in GSC (until all done)
Tuesday (60 min)
✍️ Write or outline 1 new blog post
Use ChatGPT for first draft, then edit for authenticity
Add internal links to/from new post
Request indexing for new post in GSC
Wednesday (30 min)
🔧 Ship 1 small improvement to existing tool
Or add internal links to 5 existing tool pages
Or improve 1 blog post (add FAQ, expand word count)
Thursday (45 min)
🔧 Work on tool roadmap (Phase 1 first)
Build or improve 1 tool feature
Add affiliate links to any new content
Friday (30 min)
📝 Review Clarity heatmaps — any UX issues?
💾 Back up dashboard progress
Note 3 wins from this week + 3 goals for next week
🔒 Check UptimeRobot for any downtime alerts this week
Weekend (Optional)
📖 Read 1 SEO article or tool website case study
Answer Reddit questions about PDF/image tools
Check competitor sites for new features/content ideas
📈 Monthly Review Checklist
Monthly GA4 review — which pages brought the most traffic?
Monthly GSC review — which keywords are you ranking for?
Revenue review — which stream earned most? Double down on it.
Backup dashboard progress to Google Doc or Notion
Set goals for next month based on what worked
Run npm audit on frontend + pip safety check on backend
Check securityheaders.com score — should remain A or B
Check Sentry for any unresolved errors from past month
Verify SSL certificate still Active in Cloudflare
📝 Notes & Planning
Your personal scratchpad. Notes save automatically with "Save Progress". Use these for ideas, blockers, wins, or anything else.
🔥 Active Notes / Current Focus
💡 Ideas & Future Features
🎯 Wins & Milestones
🗺️ App Architecture
Complete picture of how Documateo is built — what talks to what, and where everything lives. Your one-stop technical map.
Golden Rule: Frontend = Cloudflare Pages (static React). Backend = FastAPI on VPS. Database = PostgreSQL on same VPS. Payments = Razorpay. Everything connects via REST API over HTTPS.
🏗️ System Architecture — Big Picture
┌──────────────────────────────────────────────────────┐
│ USER BROWSER │
└────────────────────────┬─────────────────────────────┘
│ HTTPS
▼
┌──────────────────────────────────────────────────────┐
│ CLOUDFLARE PAGES (documateo.com) │
│ • Serves React build (dist/ folder) │
│ • Cloudflare Function (_worker.js) for SEO/SSR │
│ • Auto-deploy: push to GitHub → Cloudflare builds │
└────────────────────────┬─────────────────────────────┘
│ API calls to backend
▼
┌──────────────────────────────────────────────────────┐
│ VPS SERVER — 178.104.75.35 │
│ User: documateo (NEVER root in production) │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ FastAPI Backend (Python) │ │
│ │ Port: 8000 │ Entry: app/main.py │ │
│ │ Managed by: systemd service │ │
│ │ Path: /home/documateo/documateo-backend/ │ │
│ └──────────────────┬─────────────────────────┘ │
│ │ SQL queries │
│ ▼ │
│ ┌────────────────────────────────────────────┐ │
│ │ PostgreSQL │ Port: 5432 │ │
│ │ DB: documateo │ User: documateo_user │ │
│ └────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
│ │
▼ ▼
Razorpay Brevo Email
(Payments API) (future — email list)
📂 Project Folder Structure
DOCUMATEO-LIVE/
├── .venv/ ← Python virtual env (local only)
├── documateo-backend/ ← FastAPI Python app
│ ├── app/ ← All backend code lives here
│ │ ├── main.py ← FastAPI entry point
│ │ ├── models.py ← DB table definitions (SQLAlchemy)
│ │ ├── schemas.py ← Request/response shapes (Pydantic)
│ │ ├── database.py ← DB connection setup
│ │ ├── config.py ← Settings loaded from .env
│ │ └── routers/ ← API route handlers
│ │ ├── auth.py ← Login, signup, JWT tokens
│ │ ├── payments.py ← Razorpay orders & webhooks
│ │ ├── subscriptions.py ← Plan management
│ │ ├── tools.py ← Tool usage tracking
│ │ └── users.py ← User profile / admin
│ ├── alembic/ ← DB migration files
│ ├── alembic.ini ← Migration config
│ ├── requirements.txt ← Python dependencies
│ ├── .env ← ⚠️ SECRET — never commit!
│ ├── backup.sql ← DB backup (keep updated!)
│ ├── Dockerfile ← Docker config (optional)
│ └── seed_tools.py ← Seeds the tools table
│
└── documateo-frontend/ ← React (Vite) app
├── src/ ← All React code here
│ ├── pages/ ← Route-level pages
│ │ ├── tools/ ← One file per tool
│ │ ├── Dashboard.jsx ← User dashboard
│ │ └── Pricing.jsx ← Pricing page
│ ├── components/ ← Shared UI components
│ ├── hooks/ ← Custom React hooks
│ ├── api.js ← Axios client (all backend calls)
│ └── App.jsx ← Router / app entry
├── dist/ ← Built output → deployed to Cloudflare
├── functions/ ← Cloudflare Pages Functions
├── public/ ← Static assets + sitemap.xml
├── .env ← Dev env vars
├── .env.production ← Production env vars
└── index.html ← HTML template
🔄 How Frontend & Backend Talk
React makes HTTP requests to FastAPI. FastAPI queries PostgreSQL. Frontend never touches the DB directly. JWT token is the handshake.
- 1Page load: User visits documateo.com → Cloudflare serves React app + SSR HTML for bots via the Worker function.
- 2Login: React calls
POST /api/auth/login→ FastAPI validates credentials → returns JWT token → React stores token in localStorage. - 3Tool use: React calls
POST /api/tools/usewith JWT in Authorization header → backend checks subscription plan → allows/blocks → logs usage to DB. - 4Payment: React calls
POST /api/payments/create-order→ FastAPI creates Razorpay order → user pays → Razorpay sends webhook to/api/payments/webhook→ FastAPI upgrades user plan in DB. - 5API base URL is set in
documateo-frontend/.env.productionasVITE_API_URL. Currently:http://178.104.75.35:8000
📊 Database Tables
| Table | What it stores | Key columns |
|---|---|---|
| users | All registered users | id, email, role, plan, created_at |
| tools | Master list of all tools | slug, category, required_plan |
| tool_usages | Each time a user runs a tool | user_id, tool_slug, used_at |
| payments | Razorpay orders & status | id, razorpay_order_id, status, amount |
| subscriptions | Active subscriptions per user | user_id, plan, start_date, end_date, status |
| usage_logs | Detailed usage events | user_id, action, metadata, created_at |
🔌 Open Ports on VPS
| Port | Service | Notes |
|---|---|---|
| 22 | SSH | Server access — keep this open always |
| 8000 | FastAPI Backend | Public — frontend calls this port |
| 5432 | PostgreSQL | ⚠️ Open to 0.0.0.0 — restrict to your IP when migrations are done |
🔑 Environment Variables
All secret and config values your app needs. Never commit .env files to GitHub — they're in .gitignore for a reason.
NEVER commit .env files to git. They contain DB passwords, API keys, and JWT secrets. Verify
.gitignore has .env in both frontend and backend folders right now.🐍 Backend —
documateo-backend/.env# Database — PostgreSQL on VPS
DATABASE_URL=postgresql://documateo_user:YOUR_DB_PASSWORD@localhost:5432/documateo
# JWT Auth — use a long random string, never change once set
SECRET_KEY=your-long-random-secret-key-here
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=1440
# Razorpay — from dashboard.razorpay.com → Settings → API Keys
RAZORPAY_KEY_ID=rzp_live_XXXXXXXX
RAZORPAY_KEY_SECRET=XXXXXXXXXXXXXXXXXXXXXXXX
# App settings
ENVIRONMENT=production
ALLOWED_ORIGINS=https://documateo.com,https://www.documateo.com
⚛️ Frontend —
documateo-frontend/.env.production# Backend API URL — where React sends all API calls
VITE_API_URL=http://178.104.75.35:8000
# Once you add SSL to backend, update to: https://api.documateo.com
# Razorpay public key (KEY_ID only — safe to expose)
VITE_RAZORPAY_KEY_ID=rzp_live_XXXXXXXX
VITE_APP_URL=https://documateo.com
🔁 How to Update Env Variables
🖧 Server & Database
How to SSH in, manage services, run DB queries, backup, restore, and run migrations. All commands are copy-paste ready.
🔐 SSH Into Server
# ALWAYS log in as documateo — never root in production
ssh documateo@178.104.75.35
# Need sudo/root for something? Once inside:
sudo su -
# Exit root back to documateo:
exit
🔄 systemd — Manage the Backend Service
# Check if backend is running
sudo systemctl status documateo
# Restart backend (after code or .env changes)
sudo systemctl restart documateo
# Start / Stop
sudo systemctl start documateo
sudo systemctl stop documateo
# View live logs (Ctrl+C to exit)
sudo journalctl -u documateo -f
# View last 100 log lines
sudo journalctl -u documateo -n 100
# Make backend auto-start on server reboot
sudo systemctl enable documateo
🗄️ Connect to Database
# From VPS (fastest — no password prompt if you're the right user)
ssh documateo@178.104.75.35
psql -U documateo_user -d documateo
# From your LOCAL machine
psql -h 178.104.75.35 -U documateo_user -d documateo
# Quick one-liner query (no interactive session)
psql -h 178.104.75.35 -U documateo_user -d documateo -c "SELECT COUNT(*) FROM users;"
🧾 Useful DB Queries — Copy-Paste Ready
-- Show all tables
\dt
-- Health check: row counts across all tables
SELECT relname AS table_name, n_live_tup AS row_count
FROM pg_stat_user_tables ORDER BY n_live_tup DESC;
-- Count each main table
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM payments;
SELECT COUNT(*) FROM subscriptions;
SELECT COUNT(*) FROM tool_usages;
SELECT COUNT(*) FROM usage_logs;
-- Recent users
SELECT id, email, role FROM users ORDER BY id DESC LIMIT 10;
-- Recent payments
SELECT id, razorpay_order_id, status FROM payments ORDER BY id DESC LIMIT 10;
-- Active subscriptions
SELECT u.email, s.plan, s.status, s.end_date
FROM subscriptions s JOIN users u ON u.id = s.user_id
WHERE s.status = 'active';
-- Recent activity log
SELECT * FROM usage_logs ORDER BY id DESC LIMIT 10;
-- Tool access rules
SELECT slug, category, required_plan FROM tools ORDER BY category;
-- Exit psql
\q
💾 Backup & Restore Database
# BACKUP — from your LOCAL machine (saves to current folder)
pg_dump -h 178.104.75.35 -U documateo_user -d documateo > backup_$(date +%Y%m%d).sql
# BACKUP — from VPS itself
ssh documateo@178.104.75.35
pg_dump -U documateo_user -d documateo > ~/backup_$(date +%Y%m%d).sql
# Download backup from VPS to local machine
scp documateo@178.104.75.35:~/backup_20260130.sql ./
# RESTORE — import .sql file into database
psql -h 178.104.75.35 -U documateo_user -d documateo -f backup_20260130.sql
# AUTOMATED DAILY BACKUP — add this to crontab on VPS
# Run: crontab -e then add this line:
0 2 * * * pg_dump -U documateo_user documateo > /home/documateo/backups/db_$(date +\%Y\%m\%d).sql
⚠️ Do a manual backup at minimum once a week until automated backups are set up. Keep at least 3 recent backups. One copy locally, one in Google Drive.
🔄 Database Migrations (Alembic)
Use Alembic whenever you change
models.py — add/remove columns, rename tables, etc. Run from your LOCAL machine inside documateo-backend/# Check current migration status
alembic current
# Create new migration after changing models.py
alembic revision --autogenerate -m "add column xyz to users"
# Apply migrations to live database
alembic upgrade head
# Roll back one migration (if something broke)
alembic downgrade -1
# View full migration history
alembic history
🔥 Firewall (UFW) Commands
# Check firewall status
sudo ufw status
# Open a port
sudo ufw allow 8000
# Restrict DB port to your IP only (safer!)
sudo ufw delete allow 5432
sudo ufw allow from YOUR_IP_ADDRESS to any port 5432
# Reload after changes
sudo ufw reload
🚀 Deploy Guide
How to push updates to both frontend and backend. Step by step, dummy-proof.
Deploy flow in one line: Frontend = push to GitHub → Cloudflare auto-builds. Backend = push to GitHub → SSH in → git pull → restart service.
⚛️ Frontend Deploy (Auto via Cloudflare)
── On your LOCAL machine ──
cd documateo-frontend
# Make your changes in src/
# Test locally first:
npm run dev
# Open http://localhost:5173
# When happy, commit and push:
git add .
git commit -m "feat: what you changed"
git push origin main
# Cloudflare Pages will auto:
# 1. Detect the push
# 2. Run: npm run build
# 3. Deploy dist/ to CDN — takes ~2 minutes
# Monitor at: Cloudflare Dashboard → Pages → documateo → Deployments
💡 Cloudflare Pages settings: Build command =
npm run build · Output directory = dist · Root = documateo-frontend · Branch = main🐍 Backend Deploy (Manual — SSH to VPS)
── STEP 1: On your LOCAL machine ──
cd documateo-backend
# Edit your code, test locally:
source ../.venv/bin/activate
uvicorn app.main:app --reload
# (Ctrl+C to stop)
# Commit and push:
git add .
git commit -m "fix: describe change"
git push origin main
── STEP 2: On the VPS ──
ssh documateo@178.104.75.35
cd documateo-backend
# Pull latest code
git pull origin main
# If requirements.txt changed, install new deps:
source venv/bin/activate
pip install -r requirements.txt
# If models.py changed, run migrations:
alembic upgrade head
# Restart the service
sudo systemctl restart documateo
# Verify it started OK
sudo systemctl status documateo
sudo journalctl -u documateo -n 20
🛠️ How to Add a New Tool Page
- 1Create
documateo-frontend/src/pages/tools/YourTool.jsx— copy an existing tool page as a template. - 2Add the route in
src/App.jsx:<Route path="/tool/your-tool" element={<YourTool />} /> - 3Add tool to the backend
toolstable — editseed_tools.pyand run it, or insert directly via SQL:INSERT INTO tools (slug, category, required_plan) VALUES ('your-tool', 'pdf', 'free'); - 4Add the URL to
documateo-frontend/public/sitemap.xml. - 5Push to GitHub → Cloudflare auto-deploys → Go to GSC → URL Inspection → paste new URL → Request Indexing.
📦 If You Add a New Python Package
# On LOCAL machine:
source ../.venv/bin/activate
pip install new-package-name
pip freeze > requirements.txt
git add requirements.txt && git commit -m "add: new-package" && git push
# On VPS after git pull:
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart documateo
✅ Health Checks
Run Quick Check daily (5 min). Full Check weekly (30 min). Emergency checklist when something breaks.
⚡ Quick Check — Daily (5 mins)
- 1Site loads: Open
https://documateo.comin incognito. Does it load? Can you run a tool? - 2Backend alive:
curl http://178.104.75.35:8000/health— should return a 200 response. - 3Service status: SSH in →
sudo systemctl status documateo→ must say active (running) in green. - 4DB alive:
psql -U documateo_user -d documateo -c "SELECT COUNT(*) FROM users;"— if it returns a number, DB is healthy. - 5GSC: Open Google Search Console → Coverage → check for any new errors.
🔍 Full Check — Weekly (30 mins)
- 1Server resources:
df -h(disk) andfree -h(RAM). If disk >80% full, clean up logs first. - 2Review app logs:
sudo journalctl -u documateo -n 200— scan for ERROR or WARNING lines. Fix recurring ones. - 3DB backup: Run
pg_dump -h 178.104.75.35 -U documateo_user -d documateo > backup_$(date +%Y%m%d).sqland save it. - 4DB row counts: Run the health check query — confirm counts are growing as expected. Sudden drops = data issue.
- 5GSC Performance: Check which queries you're appearing for. Update page titles for any URL with high impressions but low CTR.
- 6System updates:
sudo apt update && sudo apt list --upgradable— apply security patches monthly. - 7Test payment flow: Go through Razorpay test mode — confirm order creation and webhook work end to end.
🚨 Emergency — Backend Is Down
If the site can't call the API or users can't log in, do these in order:
- 1SSH in:
ssh documateo@178.104.75.35 - 2Check status:
sudo systemctl status documateo— read the error message in red text. - 3Read logs:
sudo journalctl -u documateo -n 50— the error is almost always in the last 10 lines. - 4Try restarting:
sudo systemctl restart documateo— fixes 80% of transient issues. - 5If restart fails, check DB:
sudo systemctl status postgresql— restart it if it's stopped. - 6Check disk space:
df -h— if 100% full, clear old logs:sudo journalctl --vacuum-size=100M - 7Run manually to see full error:
cd ~/documateo-backend && source venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port 8000
🧹 Housekeeping
Routine maintenance to keep the server clean, fast, and secure. Monthly is minimum.
📅 Monthly Server Maintenance
ssh documateo@178.104.75.35
# 1. Update system packages (security patches)
sudo apt update && sudo apt upgrade -y
# 2. Remove unused packages
sudo apt autoremove -y
# 3. Rotate logs (keeps last 200MB of journal logs)
sudo journalctl --vacuum-size=200M
# 4. Clean tmp files
sudo rm -rf /tmp/*
# 5. Database vacuum (frees space from deleted rows)
psql -U documateo_user -d documateo -c "VACUUM ANALYZE;"
# 6. Check disk space after cleanup
df -h
📁 Log File Locations
| Log type | Command to view it |
|---|---|
| Backend app logs | sudo journalctl -u documateo -f |
| PostgreSQL logs | sudo tail -f /var/log/postgresql/postgresql-*.log |
| System auth logs | sudo tail -f /var/log/auth.log |
| Firewall logs | sudo tail -f /var/log/ufw.log |
| App error logs | ls ~/documateo-backend/logs/ |
🔒 Security To-Do (Outstanding)
✅
New user created (documateo) — root SSH disabled
PermitRootLogin no in /etc/ssh/sshd_config ✓
✅
UFW Firewall enabled
SSH, API port 8000, DB port 5432 open. All others blocked.
⚠️
PostgreSQL open to 0.0.0.0 — restrict when ready
sudo ufw delete allow 5432 && sudo ufw allow from YOUR_IP to any port 5432
⚠️
SSH password auth still enabled
Set up SSH keys first, then set PasswordAuthentication no in /etc/ssh/sshd_config
🔴
No fail2ban installed
sudo apt install fail2ban -y && sudo systemctl enable fail2ban && sudo systemctl start fail2ban
🔴
No automated DB backups
Run crontab -e on VPS → add:
0 2 * * * pg_dump -U documateo_user documateo > /home/documateo/backups/db_$(date +\%Y\%m\%d).sql🔴
Backend API has no SSL (HTTP only)
Get domain for API (api.documateo.com), add Let's Encrypt SSL, update VITE_API_URL in frontend to https://.
🔄 Full Stack Restart (When Everything Feels Off)
ssh documateo@178.104.75.35
# 1. Restart PostgreSQL first
sudo systemctl restart postgresql
# 2. Wait for DB to be ready
sleep 3
# 3. Restart backend
sudo systemctl restart documateo
# 4. Verify both are running
sudo systemctl status postgresql
sudo systemctl status documateo