Skip to main content
Early access — new tools and guides added regularly
🟢 Zero to Claude Code — Guide 11 of 11
View track
>_ claude codeIntermediate30 min

Working with APIs: Connecting Your App to the World

Understand REST APIs, authentication, rate limiting, and error handling. Build a weather dashboard that pulls live data from a public API.

What you will build
A deployed weather dashboard pulling live data from a public API

What APIs are and why they matter

An API, or Application Programming Interface, is how software talks to other software. When you check the weather on your phone, the app is not measuring temperature itself — it calls a weather API that returns the data. When you log in with Google on a website, the website calls Google's authentication API. When a payment is processed, the checkout calls Stripe's payment API. APIs are the plumbing of the modern internet. Almost every useful application connects to at least one external API. Understanding APIs unlocks an enormous range of possibilities: you can pull data from anywhere including weather, stocks, news, and social media. You can connect to services like email, payments, and storage. You can integrate AI models from OpenAI, Anthropic, and others into your applications. The most common API style is REST, which stands for Representational State Transfer. REST APIs use standard HTTP methods: GET retrieves data, POST creates data, PUT updates data, and DELETE removes data. You send a request to a URL called an endpoint, and the API sends back a response, usually in JSON format. For example, sending a GET request to a weather API endpoint returns a JSON object with temperature, conditions, and other data. You do not need to understand the server that generated this data. You just need to know the URL and the format of the response. That is the power of APIs — they abstract away complexity behind a simple interface.

REST basics: methods, endpoints, and status codes

Let us make our first API call from the terminal. The curl command sends HTTP requests: `curl https://jsonplaceholder.typicode.com/posts/1`. This calls a free test API and returns a JSON object with an id, title, body, and userId. That is a GET request — the default method. For a POST request that creates data: `curl -X POST -H 'Content-Type: application/json' -d '{"title":"My Post","body":"Hello world","userId":1}' https://jsonplaceholder.typicode.com/posts`. The -X flag sets the method, -H adds a header telling the API we are sending JSON, and -d is the data payload. The API responds with the created object including a new id. Headers are metadata sent with every request. Content-Type tells the API what format your data is in. Authorization sends your API key or token. Accept tells the API what format you want the response in. Status codes tell you what happened: 200 means success, 201 means a resource was created, 400 means you sent bad data, 401 means unauthorized indicating a bad or missing API key, 404 means the endpoint does not exist, 429 means you are sending too many requests and have been rate limited, and 500 means the server had an internal error. Memorise 200, 401, 404, and 500 — you will see these constantly. Every API response includes a status code. Your code should always check it before attempting to process the response data.

Making API calls in JavaScript

In a web application, you use JavaScript's built-in fetch function instead of curl. The simplest fetch call looks like: `const response = await fetch('https://jsonplaceholder.typicode.com/posts/1'); const data = await response.json(); console.log(data);`. The await keyword tells JavaScript to wait for the network response before continuing. The response.json() method parses the JSON response into a JavaScript object you can work with. For POST requests: `const response = await fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'My Post', body: 'Hello world', userId: 1 }) });`. The second argument to fetch is an options object specifying the method, headers, and body. Always check the response status before using the data: `if (!response.ok) { throw new Error('API request failed with status ' + response.status); }`. The response.ok property is true for status codes 200 through 299 and false for everything else. In Next.js, you can call APIs from server components for data fetching at build time or request time, or from client components for data fetching in the browser. Server-side fetching is preferred because it hides API keys from the user's browser and the responses can be cached. Ask Claude Code to create a server component that fetches data from an API URL and displays it, handling loading and error states properly.

API keys and authentication

Most useful APIs require authentication — they need to know who is making the request. The simplest form is an API key: a long string of characters that identifies your account. You get API keys by signing up on the API provider's website. For our weather dashboard project, we will use OpenWeatherMap. Go to openweathermap.org, create a free account, and find your API key in the dashboard. It looks something like a1b2c3d4e5f6g7h8i9j0. Never put API keys directly in your source code. Store them in environment variables. Add to your .env file: OPENWEATHER_API_KEY=a1b2c3d4e5f6g7h8i9j0. In your code, access it with process.env.OPENWEATHER_API_KEY. In Next.js, server-side code can access all environment variables. Client-side code can only access variables prefixed with NEXT_PUBLIC_ — but you should never expose API keys to the client. Make API calls from server components or API routes, never from client-side code. Other authentication methods you will encounter include Bearer tokens sent in the Authorization header as Authorization: Bearer your-token, OAuth which is a multi-step process where users grant your app permission to access their data used by Google and GitHub and others, and API keys in query parameters appended as ?api_key=abc123. For your first projects, API key authentication is most common. The pattern is always the same: get a key from the provider, store it in .env, access it in server-side code, and include it in your API requests.

Building a weather dashboard

Let us build a real project. Create the project: `mkdir ~/projects/weather-dashboard && cd ~/projects/weather-dashboard && git init && claude`. Give Claude Code the brief: Create a Next.js weather dashboard with TypeScript and Tailwind CSS. It should show the current weather and a 5-day forecast for a city, let users search for any city, display temperature, humidity, wind speed, and weather conditions with appropriate icons, use the OpenWeatherMap API with my API key stored in .env as OPENWEATHER_API_KEY, and have a clean modern design with a gradient background that changes based on weather conditions. Claude Code will scaffold the project, create the API integration, and build the UI. The OpenWeatherMap free tier gives you current weather via the /data/2.5/weather endpoint and 5-day forecast via the /data/2.5/forecast endpoint. Both accept a city name query parameter and return JSON with temperature, conditions, humidity, and wind data. Add your API key to .env, run `npm run dev`, and you should see a weather dashboard showing data for a default city. Try searching for different cities. You should see real weather data updating live. If the API returns errors, check that your API key is valid and that it has been activated — new OpenWeatherMap keys can take up to 2 hours to become active.

Rate limiting and caching strategies

The OpenWeatherMap free tier allows 60 API calls per minute and 1,000,000 per month. Exceed these limits and you get a 429 status code meaning Too Many Requests. Rate limiting is standard across almost all APIs — it prevents abuse and ensures fair usage. Handle rate limits in your code by checking for the 429 status and implementing a wait-and-retry strategy. But prevention is better than handling. The best prevention is caching: store API responses and reuse them instead of making duplicate calls. In Next.js, you can cache fetch responses natively: `fetch(url, { next: { revalidate: 600 } })`. This caches the response for 600 seconds or 10 minutes. The first request hits the API while subsequent requests within 10 minutes use the cached data instantly. For a weather app, 10-minute caching is perfect — weather does not change that fast and your users will not notice the delay. Ask Claude Code to add caching to the weather API calls, cache current weather for 10 minutes and the forecast for 30 minutes, and show the cache age in the UI so users know how fresh the data is. For more aggressive caching, Claude Code can implement a server-side cache using a JavaScript Map object or Redis. The pattern is: check the cache before making an API call. If cached data exists and is not expired, return it immediately. Otherwise call the API, store the response in the cache with a timestamp, and return it. Every API you integrate should have a caching strategy matched to how frequently the underlying data actually changes.

Error handling for a great user experience

API calls fail. Networks drop. Servers go down. API keys expire. Rate limits are hit. Your app must handle all of these gracefully. The worst user experience is a blank screen or a cryptic error message. Ask Claude Code: Add comprehensive error handling to the weather dashboard. When the API call fails, show a friendly error message with a retry button. When the city is not found, show a suggestion to check the spelling. When the API key is invalid, show a setup instruction. Add a loading skeleton while data is fetching. Claude Code will wrap API calls in try-catch blocks, check response status codes, and render different UI states based on the result. The implementation should handle four states: loading with a skeleton or spinner, success showing the actual weather data, error showing a friendly message plus a retry button, and empty state prompting the user to search for a city. For timeout handling, use an AbortController: create a controller, set a timeout that calls controller.abort() after 5 seconds, and pass the signal to the fetch options. This prevents requests from hanging indefinitely on slow connections. For retry logic, implement a function that attempts the fetch up to 3 times with increasing delays between attempts — 1 second, then 2 seconds, then 3 seconds. Most transient failures resolve within a few retries. Test your error handling by temporarily breaking things: use a wrong API key, disconnect from the internet, search for a nonexistent city name. Each scenario should produce a helpful, non-technical error message that tells the user what went wrong and what they can do about it.

Deploying and extending your dashboard

Deploy to Vercel: push to GitHub and connect the repository. In Vercel project settings, add your OPENWEATHER_API_KEY as an environment variable under Settings then Environment Variables. Deploy and your weather dashboard is live on the internet. Extend the project with these ideas to learn new concepts. Add geolocation: tell Claude Code to detect the user's location using the browser Geolocation API and show their local weather automatically. This teaches browser APIs and permission handling. Add multiple saved cities: let users save favorite cities and show weather cards for all of them on the dashboard. This teaches state management and local storage. Add weather alerts: check for severe weather conditions in the API response and show a warning banner at the top of the page. This teaches conditional rendering and data filtering. Add a forecast chart: use a charting library to show temperature over the next 5 days as a line chart. This teaches third-party library integration. Each extension builds on the previous work and teaches a new concept. The weather dashboard is also a strong portfolio piece. It demonstrates API integration, responsive design, error handling, caching, and deployment — skills that employers and clients look for. Push the code to a public GitHub repository with a good README and include the live URL. You now have the pattern to integrate any REST API into any web application: read the documentation, get an API key, make fetch requests from server-side code, cache responses, handle errors, and display the data beautifully.

Related Lesson

AI Automation Fundamentals

This guide is hands-on and practical. The full curriculum covers the conceptual foundations in depth with structured lessons and quizzes.

Go to lesson