---
title: "Set up Amplify REST API"
section: "build-a-backend/add-aws-services/rest-api"
platforms: ["angular", "javascript", "nextjs", "react", "react-native", "vue"]
gen: 2
last-updated: "2025-11-12T13:51:09.000Z"
url: "https://docs.amplify.aws/react/build-a-backend/add-aws-services/rest-api/set-up-rest-api/"
---

export async function getStaticPaths() {
  return getCustomStaticPath(meta.platforms);
}

Using the [AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/), you can configure Amplify Functions as resolvers for routes of a [REST API powered by Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html).

## Set up REST API with Lambda Function

Create a new directory and a resource file, `amplify/functions/api-function/resource.ts`. Then, define the function with `defineFunction`:

```ts title="amplify/functions/api-function/resource.ts"
import { defineFunction } from "@aws-amplify/backend";

export const myApiFunction = defineFunction({
  name: "api-function",
});
```

Create the corresponding handler file, `amplify/functions/api-function/handler.ts`, file with the following contents:

```ts title="amplify/functions/api-function/handler.ts"
import type { APIGatewayProxyHandler } from "aws-lambda";

export const handler: APIGatewayProxyHandler = async (event) => {
  console.log("event", event);
  return {
    statusCode: 200,
    // Modify the CORS settings below to match your specific requirements
    headers: {
      "Access-Control-Allow-Origin": "*", // Restrict this to domains you trust
      "Access-Control-Allow-Headers": "*", // Specify only the headers you need to allow
    },
    body: JSON.stringify("Hello from myFunction!"),
  };
};
```

Use the [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/home.html) to create an REST API resource powered by [Amazon API Gateway](https://aws.amazon.com/api-gateway/).

```ts title="amplify/backend.ts"
import { defineBackend } from "@aws-amplify/backend";
import { Stack } from "aws-cdk-lib";
import {
  AuthorizationType,
  CognitoUserPoolsAuthorizer,
  Cors,
  LambdaIntegration,
  RestApi,
} from "aws-cdk-lib/aws-apigateway";
import { Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { myApiFunction } from "./functions/api-function/resource";
import { auth } from "./auth/resource";
import { data } from "./data/resource";

const backend = defineBackend({
  auth,
  data,
  myApiFunction,
});

// create a new API stack
const apiStack = backend.createStack("api-stack");

// create a new REST API
const myRestApi = new RestApi(apiStack, "RestApi", {
  restApiName: "myRestApi",
  deploy: true,
  deployOptions: {
    stageName: "dev",
  },
  defaultCorsPreflightOptions: {
    allowOrigins: Cors.ALL_ORIGINS, // Restrict this to domains you trust
    allowMethods: Cors.ALL_METHODS, // Specify only the methods you need to allow
    allowHeaders: Cors.DEFAULT_HEADERS, // Specify only the headers you need to allow
  },
});

// create a new Lambda integration
const lambdaIntegration = new LambdaIntegration(
  backend.myApiFunction.resources.lambda
);

// create a new resource path with IAM authorization
const itemsPath = myRestApi.root.addResource("items", {
  defaultMethodOptions: {
    authorizationType: AuthorizationType.IAM,
  },
});

// add methods you would like to create to the resource path
itemsPath.addMethod("GET", lambdaIntegration);
itemsPath.addMethod("POST", lambdaIntegration);
itemsPath.addMethod("DELETE", lambdaIntegration);
itemsPath.addMethod("PUT", lambdaIntegration);

// add a proxy resource path to the API
itemsPath.addProxy({
  anyMethod: true,
  defaultIntegration: lambdaIntegration,
});

// create a new Cognito User Pools authorizer
const cognitoAuth = new CognitoUserPoolsAuthorizer(apiStack, "CognitoAuth", {
  cognitoUserPools: [backend.auth.resources.userPool],
});

// create a new resource path with Cognito authorization
const booksPath = myRestApi.root.addResource("cognito-auth-path");
booksPath.addMethod("GET", lambdaIntegration, {
  authorizationType: AuthorizationType.COGNITO,
  authorizer: cognitoAuth,
});

// create a new IAM policy to allow Invoke access to the API
const apiRestPolicy = new Policy(apiStack, "RestApiPolicy", {
  statements: [
    new PolicyStatement({
      actions: ["execute-api:Invoke"],
      resources: [
        `${myRestApi.arnForExecuteApi("*", "/items", "dev")}`,
        `${myRestApi.arnForExecuteApi("*", "/items/*", "dev")}`,
        `${myRestApi.arnForExecuteApi("*", "/cognito-auth-path", "dev")}`,
      ],
    }),
  ],
});

// attach the policy to the authenticated and unauthenticated IAM roles
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(
  apiRestPolicy
);
backend.auth.resources.unauthenticatedUserIamRole.attachInlinePolicy(
  apiRestPolicy
);

// add outputs to the configuration file
backend.addOutput({
  custom: {
    API: {
      [myRestApi.restApiName]: {
        endpoint: myRestApi.url,
        region: Stack.of(myRestApi).region,
        apiName: myRestApi.restApiName,
      },
    },
  },
});
```

<Callout info="true">

**Frontend Authorization Configuration**: After setting up your REST API, you'll also need to configure authorization in your frontend application. See the [REST API Authorization guide](/[platform]/build-a-backend/add-aws-services/rest-api/customize-authz/) for details on configuring IAM, Cognito User Pool, API Key, or custom authorization headers.

</Callout>

## Install Amplify Libraries

<!-- Platform: javascript, angular, react, vue, react-native, nextjs -->
Use the package manager of your choice to install the Amplify JavaScript library. For example, with `npm`:

```bash title="Terminal" showLineNumbers={false}
npm add aws-amplify
```
<!-- /Platform -->

<!-- Platform: react-native -->
Use the package manager of your choice to install the Amplify JavaScript library. For example, with `npm`:

<details><summary>Instructions for React Native version 0.72 and below</summary>

  `@aws-amplify/react-native` requires a minimum iOS deployment target of `13.0` if you are using `react-native` version less than or equal to `0.72`. Open the _Podfile_ located in the _ios_ directory and update the `target` value:

  ```diff
   - platform :ios, min_ios_version_supported
   + platform :ios, 13.0
   ```

</details>

```bash title="Terminal" showLineNumbers={false}
npm add aws-amplify @aws-amplify/react-native
```
<!-- /Platform -->

## Initialize Amplify API

<!-- Platform: javascript, angular, react, vue, react-native, nextjs -->
<Callout info="true">

**Important**: Custom REST APIs require explicit configuration. Unlike built-in Amplify resources (Auth, Data), custom APIs are not automatically included when calling `Amplify.configure(outputs)`.

</Callout>

To initialize the Amplify API category you need to configure Amplify with `Amplify.configure()`.

Import and load the configuration file in your app. It's recommended you add the Amplify configuration step to your app's root entry point. For example `index.js` in React or `main.ts` in Angular.

<!-- Platform: javascript, angular, react, vue, react-native -->
```javascript title="src/main.ts"
import { Amplify } from 'aws-amplify';
import { parseAmplifyConfig } from "aws-amplify/utils";
import outputs from '../amplify_outputs.json';

const amplifyConfig = parseAmplifyConfig(outputs);

Amplify.configure(
  {
    ...amplifyConfig,
    API: {
      ...amplifyConfig.API,
      REST: outputs.custom.API, // ← Required for custom REST APIs
    },
  },
  {
    API: {
      REST: {
        retryStrategy: {
          strategy: 'no-retry', // Overrides default retry strategy
        },
      }
    }
  }
);
```
<!-- /Platform -->

<!-- Platform: nextjs -->
```tsx title="pages/_app.tsx"
import { Amplify } from 'aws-amplify';
import { parseAmplifyConfig } from "aws-amplify/utils";
import outputs from '@/amplify_outputs.json';

const amplifyConfig = parseAmplifyConfig(outputs);

Amplify.configure(
  {
    ...amplifyConfig,
    API: {
      ...amplifyConfig.API,
      REST: outputs.custom.API, // ← Required for custom REST APIs
    },
  }, 
  {
    API: {
      REST: {
        retryStrategy: {
          strategy: 'no-retry' // Overrides default retry strategy
        },
      }
    }
  }
);
```
<!-- /Platform -->

<Callout warning="true">

Make sure you call `Amplify.configure` as early as possible in your application’s life-cycle. A missing configuration or `NoCredentials` error is thrown if `Amplify.configure` has not been called before other Amplify JavaScript APIs. Review the [Library Not Configured Troubleshooting guide](/[platform]/build-a-backend/troubleshooting/library-not-configured/) for possible causes of this issue.

</Callout>

<Callout warning="true">

**Critical Configuration Step**: The line `REST: outputs.custom.API` is **required** to register your custom REST API. Without this, you'll encounter the error `API name is invalid` when trying to call your API.

</Callout>

## Troubleshooting

### "API name is invalid" Error

If you encounter the error `API name is invalid` when calling your REST API, ensure you have:

1. **Added the custom API configuration**: Include `REST: outputs.custom.API` in your `Amplify.configure()` call
2. **Used the correct API name**: The API name should match the `restApiName` defined in your `backend.ts` file
3. **Called `Amplify.configure()`**: Make sure configuration happens before any API calls

**Example of incorrect configuration** (missing custom API):
```javascript
// ❌ This will cause "API name is invalid" error
Amplify.configure(outputs); // Missing custom REST API configuration
```

**Correct configuration**:
```javascript
// ✅ This includes custom REST APIs
const amplifyConfig = parseAmplifyConfig(outputs);
Amplify.configure({
  ...amplifyConfig,
  API: {
    ...amplifyConfig.API,
    REST: outputs.custom.API, // Required for custom APIs
  },
});
```
<!-- /Platform -->
