AWS Builder Center

Build a Serverless Study Assistant with Amazon Bedrock, Lambda, and API Gateway

A step-by-step beginner tutorial for building a small serverless API that answers study questions using Claude on Amazon Bedrock, with a Lambda function, API Gateway, least-privilege IAM, and cost-saving tips.

Introduction

Learning to build with generative AI is easier when you ship something small. In this tutorial we'll build a study assistant API: you send a question, and it replies with a short, clear explanation. The stack is fully serverless:
  • Amazon API Gateway: receives the HTTP request
  • AWS Lambda: runs our Python code
  • Amazon Bedrock: provides the Claude model
By the end you'll have a working endpoint and a pattern you can reuse for summarizers, quiz generators, or Q&A bots.

Architecture

Client → API Gateway → Lambda → Amazon Bedrock (Claude) → response back to the client

Prerequisites

  • An AWS account (the Free Tier helps, but Bedrock usage is billed per use)
  • Access to a Claude model in Amazon Bedrock in your chosen Region
  • Basic Python knowledge

Step 1: Pick a model

Open the Amazon Bedrock console, go to the model catalog, and choose a Claude model available in your Region. Copy its model ID (or inference profile ID, if your Region requires one). Model IDs change over time, so always copy it from the console instead of from an old tutorial.

Step 2: Create the Lambda function

Create a new Lambda function with the Python runtime. Set the function timeout to around 30 seconds, since model calls take longer than typical Lambda work.
Add this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import json
import os
import boto3

bedrock = boto3.client("bedrock-runtime")
MODEL_ID = os.environ["MODEL_ID"]

SYSTEM_PROMPT = (
"You are a friendly study assistant for students. "
"Explain concepts simply in under 150 words and end with one practice question."
)

def lambda_handler(event, context):
try:
body = json.loads(event.get("body") or "{}")
question = body.get("question", "").strip()

if not question:
return response(400, {"error": "Please include a 'question'."})
if len(question) > 1000:
return response(400, {"error": "Question is too long."})

result = bedrock.converse(
modelId=MODEL_ID,
system=[{"text": SYSTEM_PROMPT}],
messages=[{"role": "user", "content": [{"text": question}]}],
inferenceConfig={"maxTokens": 400, "temperature": 0.3},
)

answer = result["output"]["message"]["content"][0]["text"]
return response(200, {"answer": answer})

except Exception as e:
print(f"Error: {e}")
return response(500, {"error": "Something went wrong."})

def response(status, payload):
return {
"statusCode": status,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(payload),
}
Then add an environment variable named MODEL_ID with the model ID you copied in Step 1.

Step 3: Grant least-privilege permissions

Your Lambda execution role needs permission to call Bedrock. Instead of broad admin access, attach a narrow policy:
1
2
3
4
5
6
7
8
9
10
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "*"
}
]
}
Once everything works, tighten Resource to the specific model or inference profile ARN you use.

Step 4: Expose it with API Gateway

  1. Create an HTTP API in API Gateway.
  2. Add a POST route, for example /ask.
  3. Integrate it with your Lambda function.
  4. Deploy and copy the invoke URL.

Step 5: Test it

1
2
3
curl -X POST "https://YOUR-API-ID.execute-api.YOUR-REGION.amazonaws.com/ask" \
-H "Content-Type: application/json" \
-d '{"question": "What is the difference between a process and a thread?"}'
You should get back a short explanation and a practice question.

Keeping costs under control

  • Cap output with maxTokens, as we did above.
  • Limit input length before calling the model.
  • Add throttling on your API Gateway stage so a bug or abuse can't run up a bill.
  • Set an AWS Budget alert before you share the URL with anyone.
  • Delete resources you no longer need.

Security checklist

  • Don't hardcode credentials anywhere; use the Lambda execution role.
  • Add authentication (API keys, IAM, or Amazon Cognito) before making the API public.
  • Don't log sensitive user data.

Ideas to extend it

  • Save question history in Amazon DynamoDB
  • Stream responses for a better user experience
  • Add a simple static frontend hosted on Amazon S3 and CloudFront
  • Ground answers in your own notes with a knowledge base

What I learned

Most of the work wasn't the model call. It was the surrounding engineering: input validation, permissions, timeouts, and cost controls. The AI part took a few lines, while making it safe and reliable took the rest.

Resources

Have you built something with Bedrock? Share it in the comments.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article