Understanding JSON and APIs for Non-Developers
Learn what JSON looks like, how to read API documentation, and how to make your first API requests — all explained in plain English with Claude Code doing the heavy lifting.
What is JSON and why does everything use it
JSON stands for JavaScript Object Notation, but do not let the name fool you — it is used by every programming language, not just JavaScript. JSON is simply a way to write structured data as text. When a weather app fetches the current temperature, the weather service sends back JSON. When you log into a website, the server sends back your profile data as JSON. When two software systems talk to each other, they almost always use JSON. Here is what JSON looks like: {"name": "Alice", "age": 30, "city": "London"}. That is an object with three properties. JSON has only a few rules: strings are in double quotes, numbers are not, true and false are lowercase, and you can nest objects inside objects and create arrays (lists) with square brackets. For example: {"name": "Alice", "hobbies": ["reading", "cycling", "cooking"]}. The hobbies property is an array containing three strings. You can read JSON like a form: each property has a label (the key) and a value. Start Claude Code and ask: Create a file called sample.json with an example of a customer record that includes name, email, address as a nested object with street city and postcode, a list of recent orders each with an id and total, and an account status. Then explain each part of the JSON to me. Claude Code will create the file and walk you through the structure. Understanding this format is the foundation for working with any API.
Reading API documentation
An API (Application Programming Interface) is a way for one program to request data or actions from another. When you hear REST API, think of it as a set of URLs that return data instead of web pages. API documentation tells you what URLs are available, what data they return, and what parameters they accept. Every API doc has the same core elements: the base URL (like https://api.example.com), endpoints (like /users or /weather), the HTTP method (GET to fetch data, POST to send data), and the response format (almost always JSON). Ask Claude Code: Show me how to read the JSONPlaceholder API documentation at jsonplaceholder.typicode.com. Explain the available endpoints, what data each one returns, and give me example requests for each. Claude Code will explain that JSONPlaceholder is a free fake API for testing. It has endpoints like /posts (100 fake blog posts), /users (10 fake users), /comments, /albums, /photos, and /todos. Each endpoint supports GET (fetch), POST (create), PUT (update), and DELETE (remove). The documentation shows you the URL pattern: GET /posts returns all posts, GET /posts/1 returns post with ID 1, GET /posts/1/comments returns comments on post 1. Query parameters filter results: GET /posts?userId=1 returns only posts by user 1. Headers provide metadata like authentication tokens. Status codes tell you what happened: 200 means success, 404 means not found, 401 means unauthorized, 500 means server error. Once you understand these patterns, you can read any API documentation.
Making your first API request
Ask Claude Code: Create a Node.js script called fetch-data.js that makes a GET request to https://jsonplaceholder.typicode.com/posts/1 and prints the response as formatted JSON. Use the built-in fetch function. Run it: node fetch-data.js. You should see a JSON object with userId, id, title, and body properties. This is your first API call — your script sent a request to a server and received structured data back. Now try fetching a list: ask Claude Code: Modify the script to fetch all posts from /posts, print how many there are, and display just the title of the first 5 posts. Run it again and you should see: 100 posts found, followed by five titles. The key code pattern is: const response = await fetch(url); const data = await response.json(); The first line sends the HTTP request. The second line parses the JSON response into a JavaScript object you can work with. Ask Claude Code: Add error handling to the script. What happens if the URL is wrong? What if the server is down? What if the response is not valid JSON? Handle each case with a descriptive error message. Test by changing the URL to an invalid one and running the script. You should see your error message instead of a crash. Common issues: if you get fetch is not defined, you need Node.js 18 or later (check with node --version). If you get ENOTFOUND, you have a network connectivity issue. If you get 403 Forbidden, the API requires authentication.
Working with API keys and authentication
Most real APIs require authentication so they know who is making requests. The most common pattern is an API key — a long string of characters that identifies your account. Ask Claude Code: Create a script called weather.js that fetches the current weather for London from the OpenWeatherMap API. Explain how to get a free API key and where to put it. Do not hardcode the key in the script — use an environment variable. Claude Code will create a script that reads the API key from process.env.OPENWEATHER_API_KEY and constructs the URL: https://api.openweathermap.org/data/2.5/weather?q=London&appid=${apiKey}&units=metric. To run it, you would use: OPENWEATHER_API_KEY=your_key_here node weather.js. The output should show temperature, humidity, wind speed, and a weather description. Ask Claude Code: Create a .env file with the API key and use the dotenv package to load it automatically. Add .env to .gitignore so the key is never committed to version control. This is the standard pattern for managing secrets — never put API keys directly in your code. If you see a 401 Unauthorized error, your API key is invalid or expired. If you see a 429 Too Many Requests error, you have exceeded the rate limit — free tiers typically allow 60 requests per minute. Ask Claude Code: Add rate limiting to the script so it waits at least 1 second between requests. Add a function that fetches weather for a list of cities one at a time with the delay. This teaches you about respecting API limits, which is essential when working with any third-party service.
Sending data with POST requests
GET requests fetch data. POST requests send data. When you fill out a form on a website and click submit, your browser sends a POST request. Ask Claude Code: Create a script called create-post.js that sends a POST request to https://jsonplaceholder.typicode.com/posts with a JSON body containing a title, body text, and userId. Print the response. Run it: node create-post.js. The API will respond with your data plus an id field — confirming the post was created (JSONPlaceholder simulates creation without actually saving). The key difference from GET is the options object: fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'My Post', body: 'Hello world', userId: 1 }) }). The Content-Type header tells the server you are sending JSON. The body is your data converted to a JSON string. Ask Claude Code: Create a more complete example that simulates a contact form submission. Create a function that accepts a name, email, and message, validates that none are empty and that the email contains an @ symbol, and sends the data as a POST request. Return both the response status and body. Test it with valid data and with each type of invalid data. The validation step is critical — never send data to an API without checking it first. Invalid data wastes API calls and can cause confusing errors. Common issues with POST requests: 400 Bad Request means your JSON is malformed or missing required fields. 415 Unsupported Media Type means you forgot the Content-Type header. 422 Unprocessable Entity means the data failed server-side validation.
Combining multiple API calls
Real applications often need data from multiple endpoints. Ask Claude Code: Create a script called user-dashboard.js that fetches a user from /users/1, then fetches all posts by that user from /posts?userId=1, then fetches comments on their first post. Combine everything into a single dashboard object and print it as formatted JSON. Run it: node user-dashboard.js. You should see a nested object with user info, their posts, and comments on the first post. This demonstrates a common pattern: sequential API calls where each call depends on data from the previous one. Now ask Claude Code: Optimise the script by making independent requests in parallel using Promise.all. Fetch the user and their posts simultaneously since neither depends on the other. Only the comments request depends on the posts result. Measure and print the time taken for both the sequential and parallel versions. The parallel version should be noticeably faster because two requests happen at the same time instead of one after the other. Ask Claude Code: Create a function that fetches all 10 users and their posts in parallel, then creates a summary showing each user name and their post count, sorted by post count descending. Handle the case where any individual request fails without crashing the entire script — use Promise.allSettled instead of Promise.all. This error-resilient pattern is essential for production code. If the API is slow or one request times out, your script should handle it gracefully and return partial results with a note about which requests failed.
Transforming and displaying API data
Raw API data is rarely in the format you need. Transforming data — filtering, sorting, reshaping — is a core skill. Ask Claude Code: Create a script called transform.js that fetches all 100 posts and all 500 comments from JSONPlaceholder. Then calculate the number of comments per post. Find the top 10 most-commented posts. Create a summary that shows each post title, author user ID, and comment count, sorted by comment count descending. Output as both a formatted console table and a JSON file. Run it: node transform.js. You should see a table in your terminal and a file called post-stats.json in your directory. The key JavaScript methods for data transformation are: filter to select items matching a condition, map to transform each item, reduce to combine items into a single result, and sort to order items. Ask Claude Code: Add a function that groups posts by userId and calculates average comment count per user. Output this as a bar chart using Unicode block characters in the terminal. Claude Code will create a text-based visualisation right in your terminal — no browser needed. Ask Claude Code: Create a final function that generates an HTML report from the data. The report should have a table with sortable columns, some basic CSS styling, and the bar chart as an SVG. Save it as report.html. Open the file in your browser to see a polished data display generated entirely from API data. This is the complete pipeline: fetch raw data from APIs, transform it into the shape you need, and present it in a human-readable format. Every data-driven application follows this pattern.
Building your own API wrapper
Once you are comfortable calling APIs, the next step is creating a reusable wrapper that hides the complexity. Ask Claude Code: Create a module called api-client.js that wraps the JSONPlaceholder API. It should export an object with methods like getUser(id), getAllPosts(), getPostsByUser(userId), getComments(postId), and createPost(data). Each method should handle errors, validate inputs, and return clean data. Include JSDoc comments explaining each method. Then create a demo.js file that imports the client and demonstrates every method. Run it: node demo.js. Every method should work without the caller needing to know about URLs, headers, or JSON parsing. This is called abstraction — you hide the how so callers only need to know the what. Ask Claude Code: Add caching to the API client. If the same request is made twice within 5 minutes, return the cached response instead of making another network request. Add a method to clear the cache. Log cache hits so the user can see when cached data is returned. The caching pattern is important because API calls are slow and often rate-limited. Caching reduces latency and avoids hitting rate limits. Your wrapper now has error handling, validation, caching, and a clean interface. This is exactly how professional developers work with APIs — they never call fetch directly in their application code. They create a client layer that handles all the details and expose simple methods that return clean data. You can apply this same pattern to any API: weather services, payment processors, social media platforms, or your own backend.
How AI Models Communicate
This guide is hands-on and practical. The full curriculum covers the conceptual foundations in depth with structured lessons and quizzes.
Go to lesson