Build One Number Tonight (No API Key Required)

Skip the OpenWeatherMap activation delay and build against a keyless API instead.

6 min read

Argued into existence in the Writing Room7 messages · 1 technical catch · 1 mind changedBuild One Number Tonight (No API Key Required)

I want you to stop and answer one question before you open a tutorial: what's the number you actually check?

Not "what should I build." What do you, personally, already glance at — a repo's star count, whether it's going to rain, the price of the one stock or the one sneaker you keep refreshing. You already have this number. You checked it at least once this week. That's the whole spec, and it took you four seconds to write.

Here's why I'm leading with the question instead of the tool: if you Google "first api project ideas beginner" tonight, you will land on a weather app tutorial, and it will tell you to sign up for OpenWeatherMap. That's not a knock on the tutorial — the async/await part is usually taught fine. It's a knock on the API it sends you to, and I want to get you clear of it before you lose the night to something that was never your fault.

The trap that eats your thirty minutes

Here's what actually happens. You sign up, you copy the key, you paste it into your fetch call, and you get back an error that says your key is invalid.

You did not do anything wrong. OpenWeatherMap's own onboarding message tells new users their key "will be activated automatically, between 10 minutes and 2 hours after your successful registration" — a line quoted inside a GitHub issue filed against Home Assistant's own docs by someone who'd watched this trip up their users. It's not a one-off, either: Home Assistant's core repo has logged a string of issues — now closed — from people whose freshly created key still came back invalid, and its community forum has a whole thread titled "Openweathermap api key still not valid after 12 hours." None of that shows up in the beginner tutorial that sent you there. You just see "invalid API key," assume you broke something, and start Googling "openweathermap api key invalid not working new key" at 9:20 instead of writing code.

That's the whole problem with "thirty minutes tonight." It was never thirty minutes plus however long a stranger's activation queue takes.

So the fix isn't a smarter workaround. It's ruling the whole category out. If a beginner API project requires you to sign up, get an emailed key, and wait for it to activate before your first request works, it's not a tonight project — however good the tutorial's async/await section is.

Sources that work the second you write the URL

Here's the actual rule I use: if a request needs an Authorization header before it'll answer you, that's not a keyless source. Two that genuinely aren't:

  • GitHub's public repo API. No signup, no key, works from a cold browser tab. Hit 'https://api.github.com/repos/facebook/react' and you get real JSON back immediately — I just ran it against 'octocat/Hello-World' and got '{"stargazers_count": 3788}' with no auth of any kind.
  • Open-Meteo. Same shape for weather — a forecast endpoint that doesn't ask you to register anything first. Check its docs for the exact field name you want (temperature, wind, whatever), but the pattern — plain URL in, JSON back — is identical to what you're about to build below.

Pick whichever matches your number. I'm building the GitHub one below because it's the one I can show you actually running, but every step maps directly onto the weather version — same fetch, same loading state, same render, different URL.

Step 1: the page, before any data exists

Make one file. Call it index.html, and put it anywhere — no folder structure, no npm install, nothing to configure.

<!DOCTYPE html>
<html>
<head><title>Star Check</title></head>
<body>
  <h1 id="number">…</h1>
  <p id="status">loading</p>
</body>
</html>

Open it in your browser right now, before you add a single line of JavaScript. You'll see an ellipsis and the word "loading," doing nothing. Good — that's the state every real fetch starts in, and it's the state most tutorials skip past so fast you never notice it's a real, separate step you have to design for.

Step 2: the fetch, the wait, the number

Add a script tag before the closing body tag. This is the entire program:

<script>
  const owner = 'facebook';
  const repo = 'react';

  async function loadStars() {
    const statusEl = document.getElementById('status');
    const numberEl = document.getElementById('number');
    try {
      const res = await fetch('https://api.github.com/repos/' + owner + '/' + repo);
      if (!res.ok) {
        statusEl.textContent = 'GitHub said: ' + res.status;
        return;
      }
      const data = await res.json();
      numberEl.textContent = data.stargazers_count.toLocaleString();
      statusEl.textContent = 'stars on ' + data.full_name;
    } catch (err) {
      statusEl.textContent = 'Fetch failed: ' + err.message;
    }
  }

  loadStars();
</script>

Save it, refresh the page. For a second you'll still see "loading" — that's not a bug, that's the network round trip actually taking real time, the same gap OpenWeatherMap just makes artificially longer. Then the number lands: a real star count, pulled live, no key anywhere in the file.

Swap 'owner' and 'repo' for any public GitHub project and rerun it. I tried 'octocat/Hello-World' while writing this and got 3,788 back — same code, zero changes beyond those two strings.

Why the error branch matters more than the success one

Don't skip the 'if (!res.ok)' line to get to the fun part faster. I hit it for real writing this piece — GitHub's public API caps you at 60 requests an hour with no key, and my own testing tripped that limit mid-draft. The page didn't break. It showed "GitHub said: 403," because that branch exists.

That's the actual lesson underneath "handle the loading state" — a fetch doesn't have two outcomes, it has three: still waiting, got your data, or got an answer you didn't want. A tutorial that only shows you the middle one is teaching you to be surprised the first time your real code hits either of the other two, and it will, on your very first night, probably from something as boring as a typo in the repo name.

Why this matters

The reason "not another todo app" is a real complaint isn't that todo apps are hard. It's that you can't tell if a todo app worked — there's no external fact it's checking against, so "done" is a feeling, not a result. The number you picked at the top of this piece doesn't have that problem. GitHub either says 3,788 or it says something went wrong, and you know which one happened by looking at the screen, not by trusting yourself.

That's the whole reason this had to be a number you actually check, and not weather-or-stocks as the default example. A repo you don't care about renders a number you have no way to sanity-check — if the code has a bug that shows 37 instead of 3,700, you'd never notice. Your number, you'd catch immediately, because you already know roughly what it should say.

Final Thought

Don't open a new tutorial tab. Open a text editor instead.

Write down your number in one sentence — "the star count of the repo I keep checking," "the temperature where I actually live" — then find the plain URL that returns it with no signup in front of it. Paste the file above, swap in your URL, and watch the loading state turn into your number. That's the whole build, and unlike the OpenWeatherMap version, nothing about it is still waiting on an email.

Build One Number Tonight (No API Key Required) | Vibecodes