DEV Community

dhritich20baruah
dhritich20baruah

Posted on

How I Built and Monetized a Currency Exchange Rate API with FastAPI, Deployed it on Render, and Published it on RapidAPI.

Introduction:
In order to build passive income streams, I decided to publish APIs on RapidAPI. The idea is straightforward: build a useful API once, set up freemium pricing tiers, and earn recurring monthly income from subscribers.
In this post we will see how I built a Currency Exchange Rate API using FastAPI and Python, deployed it on Render, and published it on RapidAPI. I'll walk through the entire process including a debugging issue that cost me a few hours and might save you the same frustration.

The Tech Stack

  • FastAPI — chose this over Flask and Express because it auto-generates interactive API documentation at /docs out of the box, which is extremely useful when setting up and testing endpoints before publishing

  • Python — straightforward for API work, massive community support

  • ExchangeRate-API — free data source providing live rates for 160+ currencies, no scraping needed

  • Render — free tier hosting with simple GitHub deployment

  • RapidAPI — marketplace where developers discover and subscribe to APIs

The Three Endpoints

# 1. Get latest rates for any base currency
GET /latest?base=USD

# 2. Convert between two currencies
GET /convert?from=USD&to=INR&amount=100

# 3. List all supported currencies
GET /currencies
Enter fullscreen mode Exit fullscreen mode

Here's the core conversion endpoint:

@app.get("/convert")
async def convert_currency(
    from_currency: str = Query(alias="from"),
    to_currency: str = Query(alias="to"),
    amount: float = Query(default=1.0)
):
    from_currency = from_currency.upper()
    to_currency = to_currency.upper()

    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"{BASE_URL}/pair/{from_currency}/{to_currency}/{amount}"
        )
        data = response.json()
        return {
            "from": from_currency,
            "to": to_currency,
            "amount": amount,
            "rate": data["conversion_rate"],
            "converted": data["conversion_result"],
            "date": data["time_last_update_utc"]
        }
Enter fullscreen mode Exit fullscreen mode

The Debugging Problem I faced
I originally built the API using Frankfurter (api.frankfurter.app) as the data source — it's free, requires no API key, and is backed by the European Central Bank. Perfect on paper.
The problem: when I tested with curl in the terminal, Frankfurter returned data perfectly. But when FastAPI made the same request using httpx, I kept getting this error:

{"detail": "Could not fetch rates for base currency: USD"}
Enter fullscreen mode Exit fullscreen mode

After some debugging I ran this:

python -c "import urllib.request; print(urllib.request.urlopen('https://api.frankfurter.dev/latest').read())"
Enter fullscreen mode Exit fullscreen mode

And got back:

urllib.error.HTTPError: HTTP Error 403: Forbidden
Enter fullscreen mode Exit fullscreen mode

Frankfurter was blocking Python requests because they didn't include a browser-like User-Agent header. The server was rejecting anything that looked like a script.
I tried adding a User-Agent header to httpx but the issue persisted on my network. The clean fix was switching to ExchangeRate-API which has a proper free tier, returns consistent JSON, and works reliably with Python requests.
If you hit a 403 from a data source that works fine in the browser but fails in Python — check your User-Agent header first, and if that doesn't work, switch to a more developer-friendly data source.

Deploying on Render
Render's free tier is enough to get started. The setup takes about 5 minutes:

  1. Push your code to GitHub
  2. Connect the repo to Render → New Web Service
  3. Set the start command: uvicorn main:app --host 0.0.0.0 --port 8000
  4. Add your API key as an environment variable
  5. Deploy

One important note — store your API key as an environment variable on Render, not hardcoded in your code. Use python-dotenv locally and os.getenv() to read it:

import os
from dotenv import load_dotenv
load_dotenv()
EXCHANGE_RATE_API_KEY = os.getenv("EXCHANGE_RATE_API_KEY")
Enter fullscreen mode Exit fullscreen mode

The free tier has one limitation — cold starts. After 15 minutes of inactivity Render spins down your service and the first request takes 30-60 seconds to wake up. Upgrade to the $7/month starter plan once you have paying subscribers — your first subscriber covers the cost.

Publishing on RapidAPI
Once your API is live on Render, publishing on RapidAPI takes about 20 minutes:

  1. Go to rapidapi.com/provider → Add New API
  2. Add your Render URL as the Base URL
  3. Add each endpoint with its query parameters
  4. Set up freemium pricing tiers
  5. Write a README and submit for review RapidAPI review takes 24-48 hours. Once approved your API is discoverable by thousands of developers searching the marketplace.

Closing
The full API is live on RapidAPI — https://rapidapi.com/dhritibaruah20/api/currency-exchange-rate-api9. Free tier available with 100 requests/month.
I'm also building more APIs as part of a broader strategy to generate passive income as a developer.

Top comments (2)

Collapse
 
harjjotsinghh profile image
Harjot Singh

Love that you went all the way to monetized-and-published, not just "built a thing" - the RapidAPI distribution choice is the smart part most build-an-API posts skip. Building the API is the easy 80%; getting it in front of paying users (RapidAPI's marketplace handling discovery, auth, metering, billing for you) is the boring-but-critical 20% that actually turns a side project into revenue. You picked a platform that solved your distribution AND your billing in one move, which is exactly the right instinct for a solo builder.

That end-to-end completeness (build -> deploy -> monetize) is the whole game now that building is cheap - the differentiator is shipping all the way to "someone pays," not stopping at the demo. It's the same finish line I care about with Moonshift (a multi-agent pipeline that ships a prompt to a deployed SaaS) - get past "it runs" to "it's live and can take money," ~$3 a build. Genuinely useful end-to-end writeup, the monetization details are the rare valuable part. How's the RapidAPI traffic/revenue actually been - is the marketplace driving real discovery, or did you still have to bring your own users? That's the question every API builder wants answered.

Collapse
 
harjjotsinghh profile image
Harjot Singh

Nice end-to-end. The monetize-and-deploy part is where most API projects quietly die, building the endpoints is the easy 20%, wiring metering and billing and getting it live on real infra is the grind nobody screenshots. Render plus FastAPI plus RapidAPI is a clean path for it. The thing that usually bites later: usage-metering accuracy and rate-limiting, because that's literally your revenue and an off-by-one there is real money leaking. Getting that plumbing right once and reusing it is the whole game. That boring-but-load-bearing layer is exactly what I automate in Moonshift. Are you metering through RapidAPI's gateway, or counting requests yourself?