Programming

What an API is

An API is the contract two programs talk through: one sends a request in an agreed shape and the other returns a response in an agreed shape, without either needing to know how the other works inside. Almost anything on the web whose button you press and that brings data from somewhere else has an API behind it.

  • Lesson 11 of 14
  • Beginner
  • Free, no signup

The contract between two programs, plank by plank

Your program

Does not need to know how the other side works inside

the endpoint addressmethod: GET or POSTthe parametersresponse: status code and body

The other service

Gives only what the contract says, and only as much as the quota allows

The bridge was built by the other side and the other side can change it. That is why a version number sits in an API address: while version one is alive, the response shape stays as it was.

Last checked: Facts and tool names in this lesson are re-checked against their sources on this date.

An example this very site can show you

Open this site's free site speed check and give it an address. What happens behind that button is exactly the definition of an API, and it has three parties.

Your browser sends the address to our server, our server hands the same address to Google's PageSpeed service, Google returns a structured text in JSON format full of numbers, and our server picks a few of those numbers and gives them to the page. There is no human anywhere in that chain, and none of the three programs knows how the others are written inside.

An API is that contract: a set of addresses, each taking a defined input and giving a defined output. The name stands for application programming interface, and the word interface is the important part. Like a wall socket: the shape of the socket is the contract, and you do not need to know where the electricity comes from.

And the shortest route to learning this: most web APIs today are nothing exotic, just an internet address that returns JSON text instead of an HTML page. If you can open a link in a browser, you can make your first API call.

Every call has four pieces

The first piece is the address, each one called an endpoint and doing one defined job. The second is the method: GET means I want something and POST means I am sending something to be recorded. The third is the parameters, the inputs, and the fourth is the response.

The response itself has two parts and beginners usually see only one. The first is the status code: 200 means done, 400 means your request was faulty, 404 means no such thing, 429 means you asked too quickly, and 500 means something broke on their side. The second part is the body, usually JSON.

Reading that status code is what saves your time. A leading 4 means the fault is on the caller's side and the request has to be fixed; a leading 5 means the fault is on the service's side and fixing your request achieves nothing. Someone who does not know that split spends hours searching their own code while the other service was broken.

This site's own API has the same shape. There are six endpoints under the rgb/v1 namespace: the first four use GET for the domain, SEO, speed and security checks, and the other two use POST for the contact form and the view counter. Every response has one fixed envelope: a key saying whether it succeeded, plus either the data or an error message. For whoever consumes an API, that uniformity matters more than any documentation.

Keys and rate limits: why no free API is infinite

Every API call costs the other side something, which is why two instruments exist to control it. First the key: a string identifying you, so it is known whose requests these are. Second the rate limit: a ceiling on requests within a time window, and when you cross it the answer is a 429.

A real event on this site shows why both matter. Our speed tool worked against Google's API for a while with no key at all, and answered correctly. Then, with no change on our side, the same requests started coming back 429 with a daily quota of zero in the error text. The fix was one line: get a key and put it in the site's configuration. The lesson that stayed: an API's behaviour today is not tomorrow's contract, especially when you are using a service without a key.

The other side is instructive too: our own API has limits, because it is public and asks for no key at all. The ceilings are per visitor within a five minute window: 20 domain checks, 10 SEO checks, 10 security checks and 6 speed checks, because each speed check is itself an expensive call to an outside service. The contact form has its own budget of 5 submissions per hour.

If you ever write a public API yourself, take this as experience rather than advice: put the rate limit in on day one, even when it looks pointless. Adding it after a script has started hammering your service is always late.

The request ceiling of this site's tools, per five minutes

  1. domain check 20 calls the cheapest check, so the loosest ceiling
  2. SEO check 10 calls downloads the target page in full
  3. security check 10 calls carries the same kind of cost
  4. speed check 6 calls each one an expensive call to an outside service

Each ceiling is per visitor and was read from this site's own code. The contact form is not in this chart because its unit is different: five submissions per hour.

When the input comes from a visitor: the guard everyone forgets

The tools on this site share one feature that separates them from an ordinary API: the address being checked is typed by the visitor, and then our server makes a request to that address. Which means a stranger can tell our server where to connect.

If that is not restrained, somebody can write an internal network address instead of their own site. Our server, which sits inside a network and can reach places a stranger's browser cannot, would then open that address and show them the result. That class of vulnerability is called SSRF, and its remedy is well known.

The guard we wrote in this site's code does four things, and their order matters. It accepts only http and https; it accepts only ports 80 and 443; it rejects an address carrying a username and password inside it; and, most importantly, it resolves the domain name to IP addresses and checks every address that comes back, rejecting the whole request if even one of them is private or reserved.

That last clause is the one usually forgotten. Blocking addresses that carry a private IP directly is easy and everybody does it; but somebody wanting past this guard registers an ordinary looking domain that points at an internal IP. The only way to stop that is the resolution step and checking its result, not looking at the shape of the address.

Four checks before the server connects to a visitor's address

  • Only http and https

    Every other scheme is rejected, because only these two are needed for this job.

  • Only ports 80 and 443

    A non standard port usually means somebody is after another service on the same host.

  • No username or password in the address

    An address carrying credentials inside it is either a mistake or a trap.

  • Resolve the name and check every address

    The most important step and the one that gets forgotten: an ordinary domain can point at an internal IP.

This order is for an API that takes an address from a visitor. If yours takes no such input, this guard is unnecessary and other things are needed instead.

An API you do not own will fail one day

When your program connects to another service, you have created a dependency you do not control. The service can slow down, go offline, change the shape of its response or withdraw its free quota. None of those is rare, and a program written only for the success case fails on that day.

Three simple defences are almost always enough. First a timeout: every outbound call needs a ceiling on waiting, otherwise their slowness becomes your slowness. Second a cache: hold the response for a short while so a repeated input does not trigger another call. Third a second plan: when no answer arrives, the program has to know what to say.

This site's speed tool has all three and is a live example: it keeps each address's result for ten minutes, so checking the same address again makes no call to Google; and if no response comes from that service, a simpler local audit runs instead of showing an error, so the visitor is not left empty handed.

And a point usually learned only after being burnt once or twice: versioning. That v1 in our own API namespace means that if the response shape ever changes, a version two is created and whoever is connected to version one does not break. For a public API this is respect for the consumer, and it costs three extra characters in the address.

The fast path, with AI

What AI genuinely shortens here is reading an unfamiliar API's documentation and getting to the first correct call, the job that used to take half a day. But the version that works differs from "write me the code" in one way: instead of code, you first ask for one test call you can run and look at yourself. Writing code after seeing a real response takes ten minutes; writing it before is guesswork.

  1. Take the API's documentation page and send the text of that page, not just its link. If the model cannot see the page it answers from memory, and API documentation changes quickly.
  2. With the recipe below ask for a single test call that can run with no key or with a test key, and run it yourself. The first thing you see is the status code, and it tells you where you stand.
  3. Once you have the real response, hand it back and say you only need these three fields. Now the model sees the real shape of the data and the code it writes matches what actually comes back.
  4. Finally ask it to add the failure cases: a timeout, a 429, and a response that is not JSON at all. Those three are exactly the ones that never happen on the first day and certainly happen in the second month.

Copy-ready recipe

Here is the text of this API's documentation:

{documentation page text}

What I want to do: {for example, get the status of an order by its number}

Answer in this order:
1. Give me one test call I can run in a terminal right now, with the correct method, address and parameters. If a key is needed, say where it comes from and which part of the request it goes in.
2. Say which fields to look for in a successful response.
3. List the status codes this endpoint returns and what each one means.
4. Say what its rate limit or quota is. If the documentation does not state it, write that it does not, and do not guess.

Do not write any application code yet; only the test call.

Before you trust the output: Check two things yourself before running any call a model hands you. First, what that call does: a <code>GET</code> usually only reads, but a <code>POST</code> or <code>DELETE</code> may change something in your real account and undoing it is not up to you. Second, an API key is a secret: never put a real key in a command you write into a chat, and if you did it once, revoke that key and make a new one. And one thing that comes up every time: if the documentation says nothing about a request ceiling, the model will usually invent a plausible number. That number came from nowhere.

AI in this kind of work

On this topic a language model does two things well and one thing it should not do at all. Well: reading long documentation and pulling out the few lines you need, and writing the code that turns a JSON response into something usable. Not at all: producing documentation from memory. If you do not give it the documentation page, it will invent field and parameter names with complete confidence and you will spend an hour debugging code that could never have worked.

Tools that actually help

  • Claude Suited to the recipe on this page, because a long documentation text can be pasted in whole and the real API response given in the same conversation afterwards. Iran is on neither of Anthropic's two supported-countries lists; we read that on Anthropic's own page.
  • Claude Code More useful when you are writing a whole integration rather than one call, because it sees the project's code and can run the test call itself. It installs free but does not run without a Claude subscription or an Anthropic Console account.
  • Gemini For turning a JSON response into code and for repetitive mechanical work, a fast cheap model is enough. Google's own page says the Gemini web app runs in over 230 countries and territories, and Iran is not on that list.

Where it backfires

The specific risk on this topic is an endpoint or a parameter that does not exist. A model knows the shape of common APIs well, so when it has not seen the documentation it produces something that looks like a real API: the field names are sensible, the structure seems right, and none of it exists in your service. Anthropic itself calls this class of unsupported confidence hallucination in its own documentation and explains how to reduce it; the simplest reduction for this job is handing over the documentation text.
The second risk belongs to the key. An API key is your program's password, and whoever holds it can make requests on your account and spend your quota. So a real key goes neither into a chat nor into code inside a repository; its place is a settings file outside the repository, the same thing we said in the git lesson. For how each tool can be paid for from Iran, see the buying guide.

Sources: MDN: an overview of HTTP MDN: HTTP response status codes Anthropic: reduce hallucinations Anthropic: supported countries Google: where the Gemini web app is available

Where this advice stops

This lesson is about web APIs, the ones that work over HTTP and return JSON, because that is most of what you meet today. Several things are deliberately left out: heavier authentication such as OAuth, needed when your program connects to a user's account on another service; webhooks, where the direction is reversed and the other service calls you; and styles such as GraphQL with a different contract. And one boundary that holds here too: a 200 status code only says the call went through and an answer came back. Whether the content of that answer is correct is a separate guarantee, and no API gives it.

From our own work

Everything said in this lesson about this site's own API was read from one file in this site's theme and can be seen there: six endpoints under the rgb/v1 namespace, four on GET and two on POST, none of them asking for a key and all of them rate limited per visitor. Two things in that code are rarely seen in tutorials. First the SSRF guard, which does not just look at the shape of the address: it resolves the domain name to IP addresses and rejects the whole request if any of the returned addresses is private or reserved. Second, what the speed tool does when the outside service does not answer: instead of showing an error it runs a simpler local audit, and each address's result is kept for ten minutes so no repeated call is made. The key story is real too: that same call worked without a key for a while, then started returning 429 with a daily quota of zero, and was fixed by adding one key to the site's configuration.

Real follow-up questions

What is the difference between an API and a web service?

A web service is an API reachable over a network. Not every API crosses a network; a library you call inside your own program has an API too. In everyday conversation, though, the two words are usually used to mean the same thing.

Where do I start for my first API call?

From a public API that needs no key and works over GET; open its address in a browser and look at the JSON. Once the shape of the response is familiar, make the same call with a tool like curl and then from inside code. That order removes several hours of confusion.

I got a 429, what does that mean?

It means you crossed the request ceiling and have to wait, not that your code is faulty. First see whether the service said how long to wait in its response; then, if the calls are repetitive, cache the response so there are fewer of them.