An API call is a message from your program to someone else's program, sent over HTTP, the same protocol your browser uses to load this page. You send a request that says what you want. The server sends back a response with the answer. That is the whole idea, and the fastest way to make it concrete is to send one.
By the end of this page you will have called two APIs, from two different tools, and you will know what every line of the answer means.
What you need before the first request
Three things, and you probably have two of them already.
- A terminal. Terminal on macOS, any shell on Linux, PowerShell or Windows Terminal on Windows.
- curl. A command-line program that sends HTTP requests. It ships with macOS, nearly every Linux distribution, and Windows 10 and later. Type
curl --versionto check. - An API key. A free APIVerve account gives you one immediately. Sign up, open the API keys page, and copy the key. It is a long string of letters, digits and dashes.
You will learn what the key actually is, and how to keep it safe, in lesson 3. For now, treat it like a password: paste it into your terminal, not into a chat or a public file.
Anatomy of a request
Before typing anything, look at what you are about to send. Every APIVerve request has the same parts:
GET https://api.apiverve.com/v1/numbertowords?number=4021
x-api-key: YOUR_API_KEYReading it left to right:
GETis the method. It says you want to read something. Lesson 4 covers the other common method,POST.https://api.apiverve.comis the host, the server you are talking to./v1/numbertowordsis the path.v1is the version of the API, andnumbertowordsis the id of the specific API you want. Change the id and you are calling a different API on the same server.?number=4021is the query string: inputs for the API, written asname=valuepairs after a question mark.x-api-key: YOUR_API_KEYis a header, a piece of metadata sent alongside the request. This one tells the server who you are.
The Number to Words API is a good first target for a specific reason: it is deterministic. Send the same number twice and you get the same words twice. When you are learning, that matters more than it sounds, because it means a different result can only come from a different request.
Send it with curl
Replace YOUR_API_KEY with your key and run this:
curl 'https://api.apiverve.com/v1/numbertowords?number=4021' \
-H 'x-api-key: YOUR_API_KEY'-H adds a header. The backslash at the end of the first line just continues the command onto the next line; you can write it all on one line if you prefer.
Why the quotes around the URL? Characters like ? and & mean something to your shell. Without quotes, a URL with two parameters, such as ?a=1&b=2, gets cut in half at the &, and the second half runs as a separate command. Quoting every URL is a habit worth forming on day one.
Here is what comes back:
{
"status": "ok",
"error": null,
"data": {
"number": 4021,
"words": "four thousand, twenty-one",
"ordinal": "four thousand, twenty-first",
"numberOfDigits_numeric": 4,
"numberOfDigits_words": "four",
"eachNumber": ["four", "zero", "two", "one"],
"afterDecimal": null,
"locale": "en-US"
}
}
Run the same call here, then change the number and run it again:
curl "https://api.apiverve.com/v1/numbertowords?number=4021" \
-H "x-api-key: YOUR_API_KEY"Look at data.words, then try a decimal such as 12.5 and watch afterDecimal change.
Reading the envelope
The response is JSON, a text format for structured data. Lesson 2 is all about reading it. For now, notice the outer shape, because it never changes.
Every APIVerve response, from every one of its APIs, has exactly three top-level keys:
| Key | When the call worked | When it failed |
|---|---|---|
status | "ok" | "error" |
error | null | A sentence explaining what went wrong |
data | The result | null |
This outer wrapper is called an envelope. The useful part is always inside data, and its contents depend on which API you called. The envelope itself is identical whether you are converting a number, validating an email or looking up a country, which means the code you write to check for success works for every API you will ever call here.
The first thing your code should check is status. Do not look at data and guess. A failed call has data: null, and code that reaches straight for data.words crashes on it with an unhelpful error instead of telling you what actually went wrong.
You call an APIVerve API and the response has "status": "error". Where do you look to find out what went wrong?
Answer the check above to continue.
From the terminal to code
curl is for poking at an API. A real program makes the same request from code. In Node 18 or later, fetch is built in, so this needs no packages.
First put the key in an environment variable, so it is not written into the file:
export APIVERVE_API_KEY='YOUR_API_KEY'On PowerShell the equivalent is $env:APIVERVE_API_KEY = "YOUR_API_KEY". Either way, the variable lasts until you close that terminal window.
Then save this as first-call.mjs:
const res = await fetch("https://api.apiverve.com/v1/numbertowords?number=4021", {
headers: { "x-api-key": process.env.APIVERVE_API_KEY },
});
const body = await res.json();
if (body.status !== "ok") {
console.error("Request failed:", res.status, body.error);
process.exit(1);
}
console.log(body.data.words);
console.log(body.data.ordinal);Run it with node first-call.mjs and you should see:
four thousand, twenty-one
four thousand, twenty-firstLine by line, this is the curl command translated:
fetch(url, { headers })sends the request. The URL and the header are the same ones you typed into curl.await res.json()reads the body and parses the JSON text into a JavaScript object.- The
ifchecks the envelope'sstatusbefore touchingdata. If something is wrong, it prints the HTTP status and theerrorsentence, which is everything you need to start debugging. body.data.wordsreaches into the envelope and pulls out one field.
The .mjs extension tells Node to treat the file as a module, which is what allows await at the top level without wrapping everything in a function.
When the first call does not work
Most first calls fail for one of a handful of reasons, and each one has a recognisable symptom.
You left YOUR_API_KEY in the command. You get a 401 and a body with "error": "unauthorized". The server is telling you it does not recognise the key, which is true: the placeholder is not a key.
The environment variable is not set in this terminal. process.env.APIVERVE_API_KEY is undefined, so the header is sent as the literal text undefined, and you get the same 401. Environment variables belong to the terminal window you set them in. Open a new window and you need to set it again.
fetch is not defined. Your Node version is older than 18. Run node --version, and upgrade if it starts with 16 or lower.
The shell complains about & or prints half a result. The URL was not quoted. Wrap it in quotes.
You get an error about a missing parameter. Check the spelling. numbr=4021 is not number=4021. The server does not recognise numbr, so as far as it is concerned you never sent number at all, and because number is required, the error sentence says so. A typo in an optional parameter is worse: an unrecognised name is dropped silently, the call succeeds, and you get a valid answer to a question you did not mean to ask. That one catches experienced developers too.
What you built, and what's next
You sent real HTTP requests to two different APIs, from the terminal and from Node. You saw that a request is a method, a URL, parameters and headers, and that every response here comes back in the same status / error / data envelope. You also met the difference between deterministic and non-deterministic APIs, which will shape how you test everything you build.
So far you have only pulled out flat fields like data.words. Real responses nest objects inside objects and lists inside those. The next lesson, Reading JSON responses, takes apart a deeply nested response and shows you how to reach any value in it without your code falling over.