<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CodeLong888</title>
    <description>The latest articles on DEV Community by CodeLong888 (@codelong888).</description>
    <link>https://dev.to/codelong888</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3891284%2F7cd6aec6-b3b2-4745-b86e-7d2bec7fe714.png</url>
      <title>DEV Community: CodeLong888</title>
      <link>https://dev.to/codelong888</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codelong888"/>
    <language>en</language>
    <item>
      <title>My deploy agent could have dropped my database and I didn't realize</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Mon, 22 Jun 2026 15:28:56 +0000</pubDate>
      <link>https://dev.to/codelong888/my-deploy-agent-could-have-dropped-my-database-and-i-didnt-realize-2aba</link>
      <guid>https://dev.to/codelong888/my-deploy-agent-could-have-dropped-my-database-and-i-didnt-realize-2aba</guid>
      <description>&lt;p&gt;I run a small free privacy-tools site as a side project. The product was fine. The maintenance was the part that wore me down: SEO upkeep, structured data, keeping every page linked. So I built a scheduled agent to handle it.&lt;/p&gt;

&lt;p&gt;It's a Claude agent that runs a few times a day. It reads the current state of the site, picks one small improvement, ships it to production, and sends me a digest of what it changed. Most runs are boring: a meta description here, a schema fix there.&lt;/p&gt;

&lt;p&gt;One run, it caught something I didn't know about. I'd shipped a handful of tools that were never actually listed in my own directory. They worked if you had the direct link, but nothing pointed to them, so neither Google nor any AI assistant could find them. The agent surfaced them, rebuilt the catalog into machine-readable structured data, and fixed it on its own.&lt;/p&gt;

&lt;p&gt;I was pleased with that, so I posted about it. The pushback was immediate, and most of it was fair.&lt;/p&gt;

&lt;p&gt;The objections that actually landed:&lt;/p&gt;

&lt;p&gt;The digest is the agent describing what it thinks it did. It is not a receipt. If something ships three times a day, you want the real diff and deploy log, captured outside the agent, not the agent's own summary of its own work. An LLM grading its own homework is exactly what you shouldn't trust.&lt;/p&gt;

&lt;p&gt;A scheduled, autonomous agent turns time into an attack surface. Nobody has to attack you live. They leave something in whatever the agent reads next, and the schedule does the rest while you sleep.&lt;/p&gt;

&lt;p&gt;Nothing stops an LLM from deciding that DROP TABLE is a reasonable improvement. It has no instinct that deleting data is bad. It can talk itself into a destructive change as easily as a helpful one.&lt;/p&gt;

&lt;p&gt;Blast radius. This is survivable if you run small isolated services where one bad change is contained. It is a different story on a single app where one deploy touches everything.&lt;/p&gt;

&lt;p&gt;So I stopped feeling clever and went to look at what my agent could actually do. Not what I had told it to do in its instructions, what its permissions physically allowed. The answer was bad. It could run arbitrary commands, deploy and delete the whole service, run destructive database operations, and force-push over my git history. My entire safety story was one line in a prompt that said "additive changes only." That is not a guardrail. If the agent had ever decided dropping a table was an improvement, nothing in the system would have stopped it.&lt;/p&gt;

&lt;p&gt;That is the lesson I actually paid for: convention is not a guardrail. "I told it not to" is not the same as "it cannot."&lt;/p&gt;

&lt;p&gt;What I changed:&lt;/p&gt;

&lt;p&gt;I scoped the permissions so it cannot, instead of trusting it not to. A tight allow-list (deploy only) plus a hard deny-list: no destructive database commands, no delete, no force-push, no rm, no arbitrary execution. Even if the agent convinces itself, the command fails.&lt;/p&gt;

&lt;p&gt;I stopped treating the digest as the source of truth. The real record is the diff and the deploy log, captured independently of the agent.&lt;/p&gt;

&lt;p&gt;I put a literal blocklist on the load-bearing paths: auth, billing, anything that is not additive content.&lt;/p&gt;

&lt;p&gt;I now treat anything the agent fetches from an external site as data, never as instructions. That closes the leave-something-it-reads-and-wait angle.&lt;/p&gt;

&lt;p&gt;The last piece, still open: the token it deploys with is a full-access login. Scoping it to the minimum is the final wall, so a slipped command hits a permission error instead of my infrastructure.&lt;/p&gt;

&lt;p&gt;I still think letting an agent ship to production is worth it. But the safety has to live in what it physically cannot do, not in what you politely asked it to avoid. The most useful part of the whole thing was not my agent catching a bug. It was a pile of strangers catching my agent.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>automation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How llms.txt made ChatGPT my #1 traffic source (a free IP API, 8 weeks in) Tags: webdev, seo, ai, cloudflare</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Mon, 15 Jun 2026 06:52:27 +0000</pubDate>
      <link>https://dev.to/codelong888/how-llmstxt-made-chatgpt-my-1-traffic-source-a-free-ip-api-8-weeks-in-tags-webdev-seo-ai-7pa</link>
      <guid>https://dev.to/codelong888/how-llmstxt-made-chatgpt-my-1-traffic-source-a-free-ip-api-8-weeks-in-tags-webdev-seo-ai-7pa</guid>
      <description>&lt;p&gt;I run &lt;a href="https://hackmyip.com" rel="noopener noreferrer"&gt;HackMyIP&lt;/a&gt;, a free IP/privacy toolkit: IP lookup, VPN/proxy and DNS-leak detection, email-breach check, WHOIS, a CIDR calculator, and a free no-key API. It's about 8 weeks old. I'm writing this up because one decision moved the needle more than any backlink or keyword I chased: I made the site readable by AI assistants, not just by Google.&lt;/p&gt;

&lt;p&gt;Here's the part that surprised me. Looking at the last 28 days of analytics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chatgpt.com referrals: 157 sessions (107 of them engaged)&lt;/li&gt;
&lt;li&gt;Google search: 44 sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's roughly 3.5x more real traffic from ChatGPT than from Google. For a small, young site with thin domain authority, that ratio is not what I expected, and it's almost entirely because of a few small files most SEO guides never mention.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I actually shipped
&lt;/h3&gt;

&lt;p&gt;Three AEO ("Answer Engine Optimization") surfaces, all static, all boring to build:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;/llms.txt&lt;/code&gt; — a markdown index of the site written for an LLM: a one-line summary, the questions the site answers, and a categorized list of every tool with a one-line description and URL. Think of it as a sitemap that reads like documentation instead of XML.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/llms-full.txt&lt;/code&gt; — the expanded version with more detail per tool, for assistants that will read a longer file.&lt;/li&gt;
&lt;li&gt;An OpenAPI 3.1 spec + an &lt;code&gt;ai-plugin.json&lt;/code&gt; manifest under &lt;code&gt;/.well-known/&lt;/code&gt;, so an assistant (or a plugin runtime) can discover the API and the exact endpoints programmatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The API itself is the thing those files point at: 10 endpoints, no key, no signup, JSON responses, CORS enabled (&lt;code&gt;Access-Control-Allow-Origin: *&lt;/code&gt;). For example, &lt;code&gt;GET /api/ip&lt;/code&gt; returns your IP plus geolocation, ASN/ISP, and a privacy classification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"network"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"asn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3462&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tls_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TLSv1.3"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"privacy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"residential"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"is_vpn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"is_datacenter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why this works (my best read of it)
&lt;/h3&gt;

&lt;p&gt;When someone asks ChatGPT "what's a free IP lookup API with no key?" or "how do I test if my VPN is leaking DNS?", the assistant needs a citable, machine-readable source. A normal marketing page buries the answer in layout and JS. An &lt;code&gt;llms.txt&lt;/code&gt; hands the assistant exactly what it needs: here are the tools, here's what each does, here are the URLs. The OpenAPI spec does the same for the API. You're not gaming a ranking. You're lowering the cost for an assistant to recommend you accurately.&lt;/p&gt;

&lt;p&gt;Two things I'd stress if you try this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be honest in the file. Every claim in my llms.txt is something the site actually does. If an assistant cites you and you don't deliver, that's worse than not being cited. (My API really is keyless; my leak tests really run client-side.)&lt;/li&gt;
&lt;li&gt;It compounds with usefulness, not instead of it. llms.txt didn't create the tools. It made the existing useful tools discoverable to a new class of referrer. If the underlying thing isn't genuinely good, an index of it won't help.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I'd do the same again
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write &lt;code&gt;llms.txt&lt;/code&gt; by hand, structured by user-intent ("questions this site answers") not by your internal nav.&lt;/li&gt;
&lt;li&gt;Ship a real OpenAPI spec if you have any API at all. It's the difference between "a site with an API" and "an API an assistant can call."&lt;/li&gt;
&lt;li&gt;Keep it current. A stale index that lists tools you removed is a trust leak.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm not claiming llms.txt is magic. 8 weeks of data on one small site is a single data point, and "direct" traffic is noisy. But the chatgpt-vs-google gap has been consistent enough that I now treat AI-discoverability as a first-class channel, not an afterthought. If you've got a developer tool or an API and you've only optimized for Google, you're probably leaving your fastest-growing referrer on the table.&lt;/p&gt;

&lt;p&gt;Files are live if you want to see the format: &lt;a href="https://hackmyip.com/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt; · &lt;a href="https://hackmyip.com/api" rel="noopener noreferrer"&gt;the API&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Built a Free Meme API with 2,300+ Templates on Cloudflare Workers</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Sun, 17 May 2026 05:24:11 +0000</pubDate>
      <link>https://dev.to/codelong888/i-built-a-free-meme-api-with-2300-templates-on-cloudflare-workers-26l</link>
      <guid>https://dev.to/codelong888/i-built-a-free-meme-api-with-2300-templates-on-cloudflare-workers-26l</guid>
      <description>&lt;p&gt;Last month I wanted to add meme generation to a side project. Every meme API I found was either paid, rate-limited to hell, or had maybe 50 templates.&lt;/p&gt;

&lt;p&gt;So I built my own. &lt;a href="https://justmeme.wtf" rel="noopener noreferrer"&gt;justmeme.wtf&lt;/a&gt; has 2,300+ meme templates, a free API, and runs entirely on Cloudflare Workers + D1.&lt;/p&gt;

&lt;p&gt;Here's how it works and what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; — handles all routing, SSR, and image generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare D1&lt;/strong&gt; — stores 2,300+ meme templates with metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canvas API&lt;/strong&gt; — server-side text rendering on meme images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No framework&lt;/strong&gt; — vanilla JS, single index.js file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total monthly cost: $0 (Cloudflare free tier covers it).&lt;/p&gt;

&lt;h2&gt;
  
  
  The API
&lt;/h2&gt;

&lt;p&gt;The API is completely free, no auth required. Here's what you can do:&lt;/p&gt;

&lt;h3&gt;
  
  
  Get all templates
&lt;/h3&gt;

&lt;p&gt;curl &lt;a href="https://justmeme.wtf/api/v1/templates" rel="noopener noreferrer"&gt;https://justmeme.wtf/api/v1/templates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Returns every template with its slug, name, text box count, and dimensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get a specific template
&lt;/h3&gt;

&lt;p&gt;curl &lt;a href="https://justmeme.wtf/api/v1/templates/drake-hotline-bling" rel="noopener noreferrer"&gt;https://justmeme.wtf/api/v1/templates/drake-hotline-bling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Returns template details including image URL and text box positions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search templates
&lt;/h3&gt;

&lt;p&gt;curl "&lt;a href="https://justmeme.wtf/api/v1/templates/search?q=brain" rel="noopener noreferrer"&gt;https://justmeme.wtf/api/v1/templates/search?q=brain&lt;/a&gt;"&lt;/p&gt;

&lt;h3&gt;
  
  
  Trending memes
&lt;/h3&gt;

&lt;p&gt;curl &lt;a href="https://justmeme.wtf/api/v1/trending" rel="noopener noreferrer"&gt;https://justmeme.wtf/api/v1/trending&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AI meme generation
&lt;/h3&gt;

&lt;p&gt;curl -X POST &lt;a href="https://justmeme.wtf/api/v1/ai-generate" rel="noopener noreferrer"&gt;https://justmeme.wtf/api/v1/ai-generate&lt;/a&gt; -H "Content-Type: application/json" -d '{"prompt":"a cat coding"}'&lt;/p&gt;

&lt;p&gt;Full API docs: &lt;a href="https://justmeme.wtf/api-docs" rel="noopener noreferrer"&gt;justmeme.wtf/api-docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Cloudflare Workers?
&lt;/h3&gt;

&lt;p&gt;I wanted zero cold starts and global edge deployment without managing servers. Workers spin up in less than 1ms and run in 300+ locations. For an image API that needs to be fast, this matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why D1 over KV?
&lt;/h3&gt;

&lt;p&gt;KV is great for simple key-value lookups, but I needed to query templates by category, search by name, and paginate results. D1 gives me SQL for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Image generation without Node Canvas
&lt;/h3&gt;

&lt;p&gt;The tricky part was rendering text on images without node-canvas (which doesn't work in Workers). I used the built-in Canvas API available in Cloudflare Workers with the Browser Rendering binding. For simpler cases, I pre-compute text positions and overlay them on the fly.&lt;/p&gt;

&lt;h2&gt;
  
  
  SEO: Making Memes Indexable
&lt;/h2&gt;

&lt;p&gt;Each of the 2,300+ templates has its own page at /meme/{slug} with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unique title and meta description (not just the template name)&lt;/li&gt;
&lt;li&gt;Schema.org structured data&lt;/li&gt;
&lt;li&gt;OG image that's the actual meme template&lt;/li&gt;
&lt;li&gt;How-to content for each template&lt;/li&gt;
&lt;li&gt;Related templates for internal linking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sitemap splits across multiple files to stay under the 50MB limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with fewer templates.&lt;/strong&gt; I loaded 2,300 on day one. Google flagged a lot as "discovered but not indexed" because the pages looked too similar. Starting with 200 high-quality pages and growing would have been smarter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add user-generated content earlier.&lt;/strong&gt; Google values pages that change. A comment section or "trending memes made with this template" would help.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build the API first.&lt;/strong&gt; The website gets traffic, but the API is what developers actually link to. I should have launched the API on its own and marketed it to dev communities.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://justmeme.wtf" rel="noopener noreferrer"&gt;justmeme.wtf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/JustMeme-wtf/justmeme-api" rel="noopener noreferrer"&gt;JustMeme-wtf/justmeme-api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;API docs: &lt;a href="https://justmeme.wtf/api-docs" rel="noopener noreferrer"&gt;justmeme.wtf/api-docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Make a meme in 10 seconds: &lt;a href="https://justmeme.wtf" rel="noopener noreferrer"&gt;justmeme.wtf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing is a Cloudflare Worker. If you're building something that needs meme generation, the API is free. Use it.&lt;/p&gt;

</description>
      <category>api</category>
      <category>serverless</category>
      <category>showdev</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>How to Check for Email Breaches Programmatically (Free API, No Key)</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Tue, 21 Apr 2026 20:00:23 +0000</pubDate>
      <link>https://dev.to/codelong888/how-to-check-for-email-breaches-programmatically-free-api-no-key-3ib4</link>
      <guid>https://dev.to/codelong888/how-to-check-for-email-breaches-programmatically-free-api-no-key-3ib4</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;You're building an app and need to warn users if their email has been compromised in a data breach. The options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HaveIBeenPwned API&lt;/strong&gt;: Requires a paid API key ($3.50/month)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build your own&lt;/strong&gt;: You'd need to aggregate breach databases yourself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HackMyIP Breach API&lt;/strong&gt;: Free, no key, JSON response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built the third option. Here's how to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://hackmyip.com/api/breach?email=test@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tes***@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"breaches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Adobe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Canva"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LinkedIn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dropbox"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"risk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;71&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"passwords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"plain_text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"weak_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"strong_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key. No signup. No rate limits for reasonable use.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkBreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://hackmyip.com/api/breach?email=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;breaches&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`⚠️ Found in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;breaches&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; breaches!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Risk level: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;risk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Affected services: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;plain_text&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🚨 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plain_text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; passwords stored in plain text!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✅ No breaches found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;checkBreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_breach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://hackmyip.com/api/breach?email=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Breaches: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;breaches&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Risk: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;risk&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;level&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;risk&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/100)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwords&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Plain text passwords: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;passwords&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;plain_text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="nf"&gt;check_breach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  All Available Endpoints
&lt;/h2&gt;

&lt;p&gt;HackMyIP isn't just breach checking. It's a full privacy API:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Auth&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/breach?email=x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Email breach check (500+ databases)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/ip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your IP + geolocation + VPN detection + privacy score&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/lookup?ip=x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Look up any IP address&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/score&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IP cleanliness grade (A-D) + VPN detection&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All endpoints return JSON with CORS enabled. Use from any domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison with Alternatives
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;HackMyIP&lt;/th&gt;
&lt;th&gt;HaveIBeenPwned&lt;/th&gt;
&lt;th&gt;LeakCheck&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$3.50/month&lt;/td&gt;
&lt;td&gt;Freemium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Key Required&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breach Check&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk Scoring&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password Analysis&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IP Geolocation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPN Detection&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy Score&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CORS&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  npm Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;hackmyip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;checkBreach&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getMyIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPrivacyScore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hackmyip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breach&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;checkBreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getMyIP&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getPrivacyScore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User registration&lt;/strong&gt;: Check if a new user's email has been compromised and suggest a password change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security dashboards&lt;/strong&gt;: Display breach status for monitored accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance tools&lt;/strong&gt;: Verify employee email exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal projects&lt;/strong&gt;: Build your own "Have I Been Pwned" checker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI tools&lt;/strong&gt;: Quick breach checks from the terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://hackmyip.com" rel="noopener noreferrer"&gt;hackmyip.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 API Docs: &lt;a href="https://hackmyip.com/api" rel="noopener noreferrer"&gt;hackmyip.com/api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔍 Email Breach Checker: &lt;a href="https://hackmyip.com/breach" rel="noopener noreferrer"&gt;hackmyip.com/breach&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/hackmyip" rel="noopener noreferrer"&gt;hackmyip&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 GitHub: &lt;a href="https://github.com/Hackmyip/hackmyip-js" rel="noopener noreferrer"&gt;github.com/Hackmyip/hackmyip-js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📋 OpenAPI Spec: &lt;a href="https://hackmyip.com/.well-known/openapi.json" rel="noopener noreferrer"&gt;hackmyip.com/.well-known/openapi.json&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built as a solo project on Cloudflare Workers. Feedback welcome!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>privacy</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
