Write a small FastAPI app with one or two endpoints, pin dependencies in requirements.txt, push to GitHub and create a Render web service with the start command uvicorn main:app --host 0.0.0.0 --port $PORT. The free tier sleeps when idle but costs nothing and gives you a public HTTPS URL with automatic docs.
Tools you need
The 10 steps
Create the project
Make a folder, create a virtual environment (python -m venv .venv) and activate it. Install fastapi and uvicorn.
Write the app
Create main.py:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="Quotes API")
QUOTES = ["Ship it.", "Measure, then improve."]
class Quote(BaseModel):
text: str
@app.get("/quotes")
def list_quotes():
return QUOTES
@app.post("/quotes", status_code=201)
def add_quote(q: Quote):
QUOTES.append(q.text)
return {"count": len(QUOTES)}Run uvicorn main:app --reload and open /docs to see the generated documentation.
Add a test
Install pytest and httpx; create test_main.py that uses fastapi.testclient.TestClient to call /quotes and assert a 200. Run pytest.
Pin dependencies
Run pip freeze > requirements.txt. Render installs exactly what is in this file.
Push to GitHub
Add a .gitignore with .venv/ and __pycache__/, commit and push.
Create the Render service
In Render, create a new Web Service from your repository. Runtime: Python. Build command: pip install -r requirements.txt. Start command: uvicorn main:app --host 0.0.0.0 --port $PORT. Choose the free instance type.
Add environment variables
In the service settings add any secrets (API keys, database URLs) as environment variables, never in code. Read them with os.environ.
Deploy and test
Render builds and gives you an onrender.com URL. Call it: curl https://<your-service>.onrender.com/quotes. Open /docs on the live URL.
Add a database (optional)
Create a free Postgres on Supabase or Neon (Render's free Postgres is deleted after 30 days), store the connection string as an environment variable and use SQLModel or SQLAlchemy to replace the in-memory list.
Document it
Put the live URL, example requests and the test command in your README. Add a GitHub Actions workflow that runs pytest on every push.
Make it yours
- A URL shortener API with a redirect endpoint.
- A weather proxy that caches an external API.
- An ML model behind
/predictusing scikit-learn and joblib.
Troubleshooting
| Problem | Fix |
|---|---|
| Service fails to start | Check the start command uses $PORT and the module name matches your file (main:app). |
| First request is slow | Free services sleep after inactivity and take some seconds to wake. Say so in your README. |
| Module not found | The package is missing from requirements.txt. Re-run pip freeze inside the virtual environment. |
Frequently asked questions
Is Render free for Python APIs?
Yes. The free web service has 750 instance hours a month, sleeps after 15 minutes without traffic (the first visitor waits about a minute) and cannot send email over SMTP ports. That is fine for demos and portfolio projects.
What are alternatives to Render?
Cloudflare Workers for JavaScript APIs and Streamlit Community Cloud for Python demos. Railway, Fly.io and Koyeb no longer give new accounts a usable free tier, so do not plan a project around them.
How do I keep the API from sleeping?
Upgrade the instance, or accept the wake-up delay. Do not use uptime pingers that violate the host's terms.
Learn this with mentors
Programmes for builders and engineers with admissions open: live classes, mentors and project work.








