Build a Serverless Greeting API on AWS

Build a public AWS greeting API with Lambda, API Gateway, and CloudWatch logs.

Introduction

30 Second Summary

Small online tools often wait quietly until someone needs them. Keeping a computer running all day for those brief moments creates work that has nothing to do with the tool itself.

In this project, you will build a public serverless API using AWS Lambda and Amazon API Gateway. You will test personalized JSON responses in Safari before tracing each invocation in Amazon CloudWatch.

What You'll Build

You will open your public /greet link with a name and watch Safari return a personalized JSON greeting on demand.

By the end of this project, you'll have:

  • A personalized public endpoint that turns ?name=Ada into Hello, Ada! in Safari.
  • A clear validation response that returns a JSON error when name is missing.
  • A request trail that lets you match each browser response to its invocation in Amazon CloudWatch.
  • Secret Mission: Add a validated language query parameter that switches greetings between English and Spanish.

Are there any prerequisites?

No prior cloud or local development experience is required. You only need an AWS account and Safari.

The guide covers the account setup path before the build begins.

Before We Start

Start by committing to what you are building and why it matters to you. This gives your hands-on work a clear purpose before you create any cloud resources.

Secure Your AWS Workspace

Your greeting API eventually becomes public. Secure account access protects the cloud resources behind that endpoint before the first function exists.

The root user has complete account access. Multi-factor authentication adds a second sign-in check to protect that identity.

A non-root session from AWS IAM Identity Center becomes your everyday route into the AWS Management Console. One AWS Region keeps AWS Lambda and Amazon API Gateway in the same workspace.

In this step, get ready to:
  • Create or access an AWS account with root-user MFA enabled when applicable.
  • Configure or use a non-root administrative identity through IAM Identity Center.
  • Select one AWS Region before opening the Lambda and API Gateway consoles.
Create or access your AWS account

AWS account access starts with the identity that owns the account. Your path depends on whether an organization already manages that access for you.

Before You Enter Payment Details

Account creation asks for payment details. Use only the official AWS pages linked below.

Tutorial-scale use is expected to cost $0 while applicable allowances or credits remain. Usage-based charges can apply otherwise.

Your next actions depend on who manages the AWS account.

✔️ I Already Use an AWS Access Portal

  • Open the AWS access portal address supplied by your administrator.
  • Sign in with your organization credentials.
  • Complete the MFA prompt when it appears.
  • Choose the Accounts tab.
  • Select the AWS account assigned for this project.
  • Choose the administrative role assigned by your administrator.

You should reach AWS Console Home through an IAM Identity Center role. Your organization manages root-user security for this account.

ⓧ I Own an AWS Account

  • Choose Root user on the AWS sign-in page.
  • Enter the email address associated with the account.
  • Complete the password prompt.
  • Complete the MFA prompt when it appears.
  • Follow the official root-user MFA guide if the account has no registered MFA device.
  • End the root session from the account menu after confirming MFA is active.

Your root identity is now reserved for account-level administration. The next substep creates the non-root route you use for everyday work.

ⓧ I Need an AWS Account

  • Visit the official AWS account sign-up page.
  • Complete the email verification flow.
  • Complete the contact information flow.
  • Complete the payment information flow.
  • Complete the identity verification flow when AWS requests it.

Account Activation Can Take Time

A new account can take several minutes to activate. AWS states that activation can sometimes take up to 24 hours.

A quiet activation screen is normal during that wait. Continue after the activation email arrives.

  • Check your inbox for the AWS activation message.
  • Return to the AWS Management Console after activation.
  • Choose Root user.
  • Sign in with the account owner credentials.
  • Follow the official root-user MFA guide to register an MFA device.
  • End the root session from the account menu after MFA is active.

Your new account is active. Its most powerful identity now has an extra sign-in check.

Having Trouble Accessing the Account?

  • Check that you are using the email address associated with the AWS account.
  • Ask your organization administrator for the AWS access portal address if the account belongs to a workplace or school.
  • Wait for the activation email before attempting to use a newly created account.

Still blocked? Help me identify the correct AWS sign-in path for my account.

Configure non-root access

Root credentials remain reserved for rare account-level tasks. IAM Identity Center gives you a separate identity with a permission set that controls what you can access.

Identity Center setup has several screens, so take it one section at a time. The finished portal becomes your normal sign-in path for this project.

✔️ I Already Use an AWS Access Portal

  • Return to the AWS access portal from the previous substep.
  • Choose the Accounts tab.
  • Select the AWS account assigned for this project.
  • Choose the administrative role assigned for this project.
  • Confirm that AWS Console Home loads under that role.

Keep this non-root session open in Safari. You use it for the rest of the project.

ⓧ I Need to Set Up IAM Identity Center

  • Temporarily sign in to the AWS Management Console as the root user.
  • Open the official IAM Identity Center console.
  • Choose Enable under Enable IAM Identity Center.
  • Choose Create AWS organization if the standalone-account prompt appears.
  • Verify the organization email if AWS sends a verification message.
  • Keep Enable multi-account permissions turned on.
  • Use the default IAM Identity Center directory as the identity source.
  • Choose Users in the IAM Identity Center navigation pane.

What Did Enabling Identity Center Change?

IAM Identity Center uses AWS Organizations to assign account access through permission sets. The default directory stores the non-root identity you create next.

  • Choose Add user.
  • Complete the user details with your own non-root identity information.
  • Open the user activation email.
  • Activate the new credentials from the email link.
  • Return to the IAM Identity Center console.
  • Choose AWS accounts under Multi-account permissions.
  • Select the management account.
  • Choose Assign users or groups.

Where You Are Now

Your non-root user exists in the Identity Center directory. The next screens connect that user to the AWS account.

  • Select the non-root user you created.
  • Choose Next.
  • Choose Create permission set.
  • Choose Predefined permission set.
  • Select AdministratorAccess under Policy for predefined permission set.
  • Choose Next.
  • Keep the default permission set details.
  • Choose Next.

What Does the Permission Set Do?

A permission set defines the access available to your Identity Center user. IAM Identity Center turns that assignment into a managed role for the selected AWS account.

  • Choose Create.
  • Return to the assignment tab in Safari.
  • Choose Refresh in the permission sets area.
  • Select the AdministratorAccess permission set.
  • Choose Next.
  • Choose Submit.
  • Wait for the account configuration process to finish.
  • End the root session from the account menu.

Your Daily Identity Is Ready

The completed assignment gives your non-root user an administrative role. Root access can now stay signed out.

  • Open the AWS access portal link from the activation email.
  • Sign in with the non-root credentials.
  • Choose the Accounts tab.
  • Select your AWS account.
  • Choose the AdministratorAccess role.
  • Confirm that AWS Console Home loads.

Keep this non-root session open in Safari. This is the session you use for every application resource in the project.

That sensitive setup is complete. Your daily console session now uses a managed non-root role.

Can't Reach AWS Console Home?

  • Confirm that the user appears in the IAM Identity Center directory.
  • Confirm that the permission set is assigned to the correct AWS account.
  • Check the activation email for the correct AWS access portal address.

Need another pair of eyes? Help me troubleshoot my IAM Identity Center assignment.

Choose one Region and open both consoles

Regional services keep their resources in the Region selected in the console header. Using one Region prevents the function and its API integration from ending up in separate locations.

  • Choose the currently displayed Region name in the AWS navigation bar.
  • Select one AWS Region close to you.
  • Record the Region you selected here: selected AWS Region.

Why Keep One Region?

AWS consoles can show different resources when their Region selectors differ. A shared Region keeps the Lambda function visible when you connect it to API Gateway later.

  • Choose the gear icon in the AWS navigation bar.
  • Choose See all user settings.
  • Choose Edit next to Localization and default Region.
  • Select selected AWS Region under Default Region.
  • Choose Save settings.
  • Choose Go to new default Region if that option appears.

The console header should now show selected AWS Region. This setting keeps your Identity Center sessions anchored to the same default Region.

  • Open the official AWS Lambda console in a new Safari tab.
  • Select selected AWS Region from the Lambda console header if needed.
  • Open the official Amazon API Gateway console in another Safari tab.
  • Select selected AWS Region from the API Gateway console header if needed.
  • Choose the account menu in the Lambda console header.
  • Confirm that the session shows your IAM Identity Center role instead of the root user.

Before you compare the console tabs, what Region label do you expect to see in both?

  • Switch to the Lambda console tab.
  • Confirm that its header shows selected AWS Region.
  • Switch to the API Gateway console tab.
  • Confirm that its header also shows selected AWS Region.

Both service consoles now show the same Region. Your Lambda tab also confirms that you are working through a non-root Identity Center role.

Do the Region Labels Differ?

  • Choose the Region name in the console tab that shows a different value.
  • Select selected AWS Region from the Region list.
  • Reload the page if the service console does not update after the selection.

Still seeing different Regions? Help me align my Lambda and API Gateway console Regions.

Your AWS workspace is secured through a non-root identity. Next, you create the Lambda function that returns your first cloud response.

Create Your Lambda Function

The secure AWS Management Console workspace from the last step is ready for its first resource. Your selected Region keeps this function in the same place as the rest of the project.

Now you'll create an AWS Lambda function that runs directly from the console. This test proves the Python handler can return a JSON response before you add networking.

In this step, get ready to:
  • Create the greet Lambda function with the Python 3.14 runtime.
  • Deploy a JSON response from lambda_function.py.
  • Invoke the function with an empty test event.
Create the Lambda function

AWS Lambda provides serverless compute that runs your handler when invoked. Its default generated execution role gives the function the AWS permissions needed for basic execution.

AWS Lambda is billed by requests and execution duration. This tutorial triggers one console test before the cleanup section helps you remove the function.

  • Switch back to the AWS Lambda console from earlier.
  • Confirm your chosen AWS Region is visible in the console header.

The console header should show the same Region you selected for this project.

  • Choose Create function.
  • Select Author from scratch.

The creation form now shows the settings for your new function.

  • Enter greet in the Function name field.
  • Select Python 3.14 for Runtime.

The form now identifies greet as a Python function in your selected Region.

  • Keep the default execution-role option selected.
  • Choose Create function.

Good progress. Your greet function now exists in the selected Region.

Can't create the function?

  • Confirm the console still shows the non-root administrative identity from the previous step.
  • Check that the console header still shows your chosen AWS Region.

Still blocked? Help me troubleshoot why I cannot create the greet Lambda function.

Add the first response

A Lambda handler turns an invocation into a returned value. This first handler returns a response dictionary with a serialized message.

  • Select lambda_function.py in the built-in code editor.

The editor should show the starter code generated with the function.

  • Select all existing code in lambda_function.py.
  • Replace it by copying the code below:
import json


def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "headers": {"content-type": "application/json"},
        "body": json.dumps({"message": "Hello, cloud!"}),
        "isBase64Encoded": False,
    }

What does this code do?

  • The import json line gives the handler a serializer for the response body.
  • The lambda_handler(event, context) function is Lambda's entry point. It receives invocation input through event.
  • The statusCode value of 200 marks the response as successful.
  • The headers field identifies the body as application/json.
  • The body field serializes Hello, cloud! into JSON text.
  • The isBase64Encoded value of False keeps the response body as regular text.
  • Choose Deploy above the editor.
  • Wait until the console confirms the code was deployed.

The deployed version of lambda_function.py is now ready for an invocation.

Deployment not completing?

  • Make sure you edited lambda_function.py.
  • Check that every opening brace has a matching closing brace.
  • Check that the response fields use matching quotation marks.

Need another pair of eyes? Help me compare my Lambda handler with the expected code.

✔️ Awesome, I've got everything!

Your deployed lambda_function.py is ready for its first test.

ⓧ I'd like to double check the full code

Compare your entire lambda_function.py file with this reference.

import json


def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "headers": {"content-type": "application/json"},
        "body": json.dumps({"message": "Hello, cloud!"}),
        "isBase64Encoded": False,
    }

Every line in this reference belongs in the deployed file.

Run the console test

A test event is the JSON input Lambda passes into event. An empty object isolates the handler because this version needs no input values.

  • Choose the Test tab on the greet function page.

You'll see the controls for creating a test event.

  • Choose Create new event under Test event.

The test event form should now show a name field and a JSON editor.

  • Enter myTestEvent in the Name field.
  • Replace the contents of Event JSON by copying this empty object:
{}

Why use an empty event?

The empty object supplies no input fields. This handler returns the same greeting for every invocation.

  • Choose Save changes.

The console now keeps the empty event ready for reuse.

Before you run the test, ask yourself whether an empty event can still produce a successful response.

  • Invoke the function by choosing Test.
  • Expand Details under Execution result.

You'll see statusCode set to 200. The serialized body contains Hello, cloud!.

That first successful invocation proves your function can answer on demand.

Test result looks different?

  • Choose Deploy again if you tested before publishing the latest editor changes.
  • Confirm the test event contains only {}.
  • Compare lambda_function.py with the full-code reference above.

Still missing the response? Help me troubleshoot my Lambda console test.

Your Lambda function can now return a JSON response on demand. Next, you'll give it a public HTTP route.

Expose a Public HTTP API

Your AWS Lambda function now returns a JSON greeting during a console test. Safari still has no public address that can invoke it.

An Amazon API Gateway HTTP API supplies the missing public route. This step connects that route to greet. You will then test how the current handler responds to a name in the URL.

In this step, get ready to:
  • Connect an HTTP API integration to greet.
  • Create greeting-http-api with its generated GET /greet route.
  • Test the public route with name=Ada.

Why use API Gateway?

A Lambda function URL offers the fastest path to a simple HTTP prototype. API Gateway exposes a route through a stage.

A separate integration connects that route to greet. This structure gives you an API-management model that can grow beyond one function.

Connect API Gateway to Lambda

An integration tells API Gateway which backend handles a request. A Lambda proxy integration sends the request details to greet as an event.

  • Switch back to the Amazon API Gateway console from earlier.
  • Confirm the Region in the console header matches the Region used for greet.

The API list now reflects the same Region as your Lambda function.

  • Choose Create API.

You'll see the API types available in the selected Region.

  • Find the HTTP API card.
  • Choose Build under HTTP API.

The HTTP API setup flow is now ready for its backend integration.

  • Choose Add integration.
  • Select Lambda as the integration type.

The console now shows the Lambda functions available in this Region.

  • Select greet from the function list.

You should see greet listed as the integration target. Requests sent through the API can now reach your function.

Create the route and public API

An HTTP route combines a request method with a resource path. The quick-create flow uses the function name to generate GET /greet.

A stage makes that route available through an invoke URL. Creating the API turns your Lambda integration into a public endpoint.

  • Enter greeting-http-api in the API name field.
  • Choose Next.

The review page now summarizes the integration that API Gateway is ready to create.

  • Confirm the integration points to the Lambda function greet.
  • Confirm the generated route is GET /greet.
  • Review the generated stage.
  • Choose Create.

Good work. greeting-http-api now gives greet a public route.

  • Copy the invoke URL from the API details.
  • Record the copied value here: your API invoke URL.

API not created?

  • Check that the API name is greeting-http-api.
  • Make sure the integration points to greet in the same Region.
  • Return to the review page if the generated route does not show GET /greet.

Still stuck? Help me troubleshoot my HTTP API setup.

Call the public route from Safari

A query parameter carries a small input value after the question mark in a URL. The value ?name=Ada lets you test how the current handler treats browser input.

  • Use Safari's tab bar to open a new tab.
  • Paste your API invoke URL into the address bar.
  • Append /greet?name=Ada to the address.

Before you send the request, do you expect the response to use Ada or stay generic?

  • Press Enter to call the public route.

You'll see a JSON response whose message is Hello, cloud!. The public route works.

The generic result is the intended shortfall. Your current lambda_handler(event, context) returns fixed content, so name has no effect.

Don't see the greeting?

  • Confirm the address begins with your recorded invoke URL.
  • Confirm the address ends exactly with /greet?name=Ada.
  • Check that greeting-http-api uses the greet integration in the same Region.

Need another pair of eyes? Help me debug why my public greeting route is not returning JSON.

Your API is public through /greet. Next, you'll make name drive the response before adding a clear missing-name error.

Personalize and Validate Greetings

The public route you built now carries browser requests from Amazon API Gateway to AWS Lambda. Yet the handler returns Hello, cloud! for every request because it never reads ?name=Ada.

A Lambda proxy integration places each query parameter inside the event object. You will use that payload to personalize a valid greeting or return a clear JSON error.

In this step, get ready to:
  • Confirm that the existing route ignores the supplied name.
  • Deploy a handler that returns a personalized greeting.
  • Verify that missing names receive a clear validation response.
Confirm the current limitation

The current handler has one hard-coded return path. A name can reach the route without influencing the response body.

Before you reload the endpoint, do you expect the visible name to change the response?

  • Switch back to the public endpoint in Safari from earlier.
  • Load the invoke URL ending in /greet?name=Ada.

You will still see Hello, cloud!. That generic result is the intended shortfall in the current handler.

How does the request reach the handler?

  • Amazon API Gateway stores the supplied name inside queryStringParameters.
  • The requestContext object carries metadata about the browser request.
  • The requestId value identifies the request that reached the function.
  • The context.aws_request_id value provides a fallback identifier for console tests.
Add a JSON response helper

Successful requests and validation errors need the same Lambda proxy response shape. A helper centralizes that shape so the handler only supplies a status code plus a payload.

  • Return to the built-in editor for the greet function in the Lambda console.
  • In lambda_function.py, add the helper directly above def lambda_handler(event, context): by pasting this code:
def json_response(status_code, payload):
    return {
        "statusCode": status_code,
        "headers": {"content-type": "application/json"},
        "body": json.dumps(payload),
        "isBase64Encoded": False,
    }


What does this helper do?

  • The status_code argument becomes the response's statusCode value.
  • The headers field labels the response body as JSON.
  • The json.dumps(payload) call converts the Python payload into the text sent to the browser.
  • The isBase64Encoded field confirms that the body contains regular text.
  • Choose Deploy above the editor.
  • Switch back to the public endpoint in Safari.
  • Reload /greet?name=Ada.

You will still receive Hello, cloud!. This result confirms that the helper deployed without disrupting the existing handler.

Deployment not completing?

  • Check that json_response() starts at the far left of the editor. Nesting it inside lambda_handler() prevents Lambda from finding the helper later.
  • Confirm that the existing import json line remains at the top of lambda_function.py.

Still stuck? Help me check the placement and indentation of my json_response helper.

Read and validate the name

The handler can now use the response helper for both outcomes. The final version reads the name before choosing the success path or the validation path.

  • In lambda_function.py, select the existing handler from def lambda_handler(event, context): through the last line of its return dictionary.
  • Replace the selection by pasting this code:
def lambda_handler(event, context):
    query = event.get("queryStringParameters") or {}
    name = str(query.get("name") or "").strip()
    request_id = event.get("requestContext", {}).get(
        "requestId",
        context.aws_request_id,
    )

    if not name:
        print(json.dumps({"requestId": request_id, "outcome": "rejected"}))
        return json_response(
            400,
            {
                "error": "Missing required query parameter: name",
                "example": "?name=Ada",
                "requestId": request_id,
            },
        )

    print(json.dumps({"requestId": request_id, "outcome": "accepted"}))
    return json_response(
        200,
        {
            "message": f"Hello, {name}!",
            "requestId": request_id,
        },
    )

What does this handler do?

  • The query variable reads queryStringParameters from the incoming event.
  • The name variable converts the supplied value to text. It also removes surrounding spaces.
  • The request_id variable uses the HTTP request identifier when one exists. It falls back to the Lambda invocation identifier.
  • The missing-name path logs a rejected outcome. It returns a status of 400 with a useful example.
  • The valid-name path logs an accepted outcome. It returns a status of 200 with the personalized message.
  • Choose Deploy above the editor.

Before you test both URLs, which request do you expect the handler to accept?

  • Load the public URL ending in /greet?name=Ada in Safari.
  • Load the public URL ending in /greet in a second Safari tab.

With name supplied, you will see a JSON body containing Hello, Ada! plus a requestId. The handler returns status 200.

Without name, you will see Missing required query parameter: name. The response includes ?name=Ada plus a requestId with status 400.

You have closed the gap. The public endpoint now responds to valid input and explains rejected requests.

Still seeing the generic greeting?

  • Confirm that you chose Deploy after replacing the handler.
  • Check that the new lambda_handler() appears only once in lambda_function.py.
  • Check that the successful URL ends in /greet?name=Ada.
  • Check that the rejected URL ends in /greet without a name value.

Need another pair of eyes? Help me debug why my deployed greeting endpoint is not personalizing or validating the name query parameter.

✔️ Awesome, I've got everything!

Your deployed lambda_function.py now handles personalized greetings plus missing-name validation.

ⓧ I'd like to double check the full code

import json


def json_response(status_code, payload):
    return {
        "statusCode": status_code,
        "headers": {"content-type": "application/json"},
        "body": json.dumps(payload),
        "isBase64Encoded": False,
    }


def lambda_handler(event, context):
    query = event.get("queryStringParameters") or {}
    name = str(query.get("name") or "").strip()
    request_id = event.get("requestContext", {}).get(
        "requestId",
        context.aws_request_id,
    )

    if not name:
        print(json.dumps({"requestId": request_id, "outcome": "rejected"}))
        return json_response(
            400,
            {
                "error": "Missing required query parameter: name",
                "example": "?name=Ada",
                "requestId": request_id,
            },
        )

    print(json.dumps({"requestId": request_id, "outcome": "accepted"}))
    return json_response(
        200,
        {
            "message": f"Hello, {name}!",
            "requestId": request_id,
        },
    )

Your endpoint now handles both request paths. Next up, you will trace those requests in Amazon CloudWatch.

Trace Requests in CloudWatch

Your public greeting API now personalizes valid requests. It also rejects requests that omit name.

A public endpoint is hard to operate without evidence of what ran. In this step, you'll use Amazon CloudWatch to link fresh browser requests to AWS Lambda invocation logs.

In this step, get ready to:
  • Generate fresh logs for both API outcomes.
  • Locate the recent Lambda invocation records in CloudWatch.
  • Correlate a browser response with its application log entry.
Send fresh browser requests

Each browser request creates a Lambda invocation. Fresh requests keep the matching records close to the top of the newest log stream.

Your endpoint is publicly callable. The sample name Ada keeps this trace safe.

Before you send the requests, picture the outcome label each path should produce.

  • Keep sensitive data out of this public endpoint.
  • Load the public endpoint URL from earlier in Safari with a path ending in /greet?name=Ada.

You should see a 200 JSON response. The message value is Hello, Ada!.

The successful response also includes a requestId value.

  • Record the successful response's requestId value here: your successful request ID.
  • Load the same public endpoint with a path ending in /greet.

You should see a 400 JSON response. Its error value explains that the required name query parameter is missing.

Inspect the newest log stream

Lambda sends invocation details to CloudWatch. Your Python print output appears in the same service.

The function's entries live in the /aws/lambda/greet log group. Generated stream names make the newest one a little fiddly to spot.

  • Switch back to the AWS Management Console tab from earlier in Safari.
  • Use the console search bar to open Amazon CloudWatch.
  • Select the log group named /aws/lambda/greet from the log groups list.
  • Choose the log stream with the freshest activity shown in the list.

You should see recent invocation entries from your browser requests. Each invocation begins with a START line.

The same invocation ends with an END line. Its REPORT line summarizes runtime usage.

Between those runtime lines, your application log shows an accepted or rejected outcome.

What does each line prove?

  • The START line marks the beginning of a Lambda invocation.
  • The application JSON line records the request outcome.
  • The same JSON line carries the requestId used for correlation.
  • The END line marks the completion of the invocation.
  • The REPORT line summarizes runtime usage for the invocation.

Don't see fresh log entries?

  • Confirm CloudWatch shows the same AWS Region selected for the function.
  • Reload the two endpoint URL variants in Safari to create newer invocations.
  • Refresh the newest log stream in CloudWatch.

Still stuck? Help me find my recent greet Lambda invocations in CloudWatch.

Match the response to its log

Your handler returns a requestId to the browser. It writes that same value into the application log.

Matching those values connects the caller's response to the exact code path that handled it.

Before you search, predict whether the successful request ID appears unchanged in the application log.

  • Press Cmd+F on macOS or Ctrl+F on Windows to open the browser's find box.
  • Search for your successful request ID.

You should land on an application JSON log entry whose requestId exactly matches the browser response. The same entry shows the accepted outcome.

  • Locate the nearby rejected application log from the request without name.
  • Confirm the recent invocation entries also include START, END, and REPORT lines.

You have the full trail now. A browser response leads you to its matching application log entry.

Secret mission

Add Multilingual Greetings

Your endpoint already personalizes greetings with a name. Extend it with a validated language option that supports English and Spanish while rejecting unsupported values.

Clean Up Your Resources

Clean Up Your Resources

Your live demo uses AWS resources that can generate usage-based charges. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Cost warning

Amazon API Gateway HTTP API charges for API calls. Data transfer can add charges.

AWS Lambda charges for requests. Execution duration can add charges.

The Amazon CloudWatch log group persists after the Lambda function is deleted. Stored logs can continue to use billable storage.

The Pause or Delete options below stop the public API from continuing to receive calls.

Resources you used:

  • Public Amazon API Gateway HTTP API named greeting-http-api with a GET /greet Lambda proxy route.
  • Python 3.14 Lambda function named greet.
  • CloudWatch log group named /aws/lambda/greet.
  • Default AWS IAM execution role created for greet.

Keep everything running

No action is needed. Choose this if you still use the public greeting API for demonstrations.

  • Keep greeting-http-api public only while you need it.
  • Avoid sending sensitive data to the public /greet endpoint.
  • Monitor your AWS usage while the API remains public.

Pause - I'll come back to this later

Removing the public endpoint can feel final. Your Lambda function remains available for later use.

  • Return to the Amazon API Gateway console from earlier.
  • Select greeting-http-api.
  • Choose Actions.
  • Choose Delete.
  • Choose Delete in the confirmation.
  • Return to the public /greet URL from earlier in Safari.

You'll see that the greeting endpoint is unavailable. The greet function remains in Lambda.

Delete - I don't want to use this again

Deleting the full stack is permanent. Your AWS account stays active.

The role name is generated by AWS, so save it before deleting the function.

  • Return to greet in AWS Lambda.
  • Open the function's configuration details.
  • Find the default execution role linked to greet.
  • Record the role name here: your Lambda execution role name.

The public entry point goes first.

  • Return to the Amazon API Gateway console from earlier.
  • Select greeting-http-api.
  • Choose Actions.
  • Choose Delete.
  • Choose Delete in the confirmation.

The public route is now removed. The Lambda function can be deleted next.

  • Return to the AWS Lambda console from earlier.
  • Select greet.
  • Choose Actions.
  • Choose Delete.
  • Choose Delete in the confirmation.

Deleting the function leaves its log group behind. Remove that stored history separately.

  • Return to Amazon CloudWatch from earlier.
  • Find the log group named /aws/lambda/greet.
  • Select /aws/lambda/greet.
  • Delete the selected log group.

The execution role can affect other resources if it was reused. Confirm that it belongs only to this project before removing it.

  • Go to AWS IAM from the signed-in AWS Management Console.
  • Find the role named your Lambda execution role name.
  • Confirm that no other AWS resource uses the role.
  • Delete the role.
  • Return to the former /greet URL in Safari.

You'll see that the public greeting endpoint is unavailable. Your API, function, logs, and generated role are now removed.

Nice Work!

Nice Work!

You did it! Your public serverless API now answers requests with personalized JSON.

You've learned how to:

  • Built a Python 3.14 function on AWS Lambda that returns structured JSON responses.
  • Published the function through an Amazon API Gateway HTTP API. The public /greet route now personalizes valid requests or rejects missing names with a 400 response.
  • Traced accepted or rejected invocations in Amazon CloudWatch. Matching requestId values connect each browser response to its START, END, or REPORT log line.
  • Completed the optional Secret Mission by adding multilingual greetings with a validated language query parameter. Unsupported values now return a clear JSON error.

Ready to quiz yourself?