> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - If a reference page seems to be missing its schema (parameters, return types, or type definitions), append `?schema=true` to its `.md` URL (e.g. `https://dev.wix.com/docs/contexts/contexts/stores/category-info/use-category-info-context.md?schema=true`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

# SubmitAppPlan

# Package: containersProjects

# Namespace: ContainersProjects

# Method link: https://dev.wix.com/docs/api-reference/mobile/containers-app/containers-projects/project-v1/submit-app-plan.md

## Permission Scopes:
Manage AppSmith Projects: SCOPE.CONTAINERS.PROJECTS

## Introduction

Validates a mobile app plan and saves it for approval.

Returns the normalized plan with its `revision` and `digest`. Show this plan to the user and,
once they approve it, call
[Approve App Generation](https://dev.wix.com/docs/api-reference/mobile/containers-app/containers-projects/project-v1/approve-app-generation.md)
with the same `revision` and `digest`.

To change a saved plan, call this method again with `proposalId` and a new `requestKey`. Each
change creates a new revision, and approval of an earlier revision is refused. A plan can have up
to 50 revisions. A saved plan expires 24 hours after it's created, at `expiresDate`.

Repeating a call with the same `requestKey` and the same plan returns the same result.

---

## REST API

### Schema

```
 Method: submitAppPlan
 Description: Validates a mobile app plan and saves it for approval.  Returns the normalized plan with its `revision` and `digest`. Show this plan to the user and, once they approve it, call [Approve App Generation](https://dev.wix.com/docs/api-reference/mobile/containers-app/containers-projects/project-v1/approve-app-generation.md) with the same `revision` and `digest`.  To change a saved plan, call this method again with `proposalId` and a new `requestKey`. Each change creates a new revision, and approval of an earlier revision is refused. A plan can have up to 50 revisions. A saved plan expires 24 hours after it's created, at `expiresDate`.  Repeating a call with the same `requestKey` and the same plan returns the same result.
 URL: https://www.wixapis.com/containers/projects/v1/app-plans
 Method: POST
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  requestKey, schemaVersion, planningContextId, catalogVersion, plan
 Method parameters: 
   param name: catalogVersion | type: catalogVersion | description: `catalogVersion` from Get App Planning Context. | required: true | validation: maxLength 100
   param name: plan | type: AppPlan | description: A mobile app plan written by an agent for the user. | required: true 
        - name: initialPrompt | type: string | description: The user's request, in their words. Not a technical implementation plan.  | validation: maxLength 10000
        - name: appSpec | type: AppPlanSpec | description: What the app does.  
           - name: appName | type: string | description: Display name of the app.  | validation: maxLength 200
           - name: appDescription | type: string | description: What users can do in the app.  | validation: maxLength 5000
           - name: businessGoal | type: string | description: The user outcome the app serves.  | validation: maxLength 2000
           - name: audience | type: string | description: The app's intended users, with any access assumptions.  | validation: maxLength 2000
           - name: features | type: array<AppPlanFeature> | description: Features of the app. At least one.  | validation: maxItems 200
              - name: title | type: string | description: Short feature title, unique in the plan.  | validation: maxLength 200
              - name: description | type: string | description: What the user does and gets, the content or data it uses, the access it needs and any significant limitation.  | validation: maxLength 2000
           - name: navigation | type: array<string> | description: Names of the app's screens, unique. At least one.  | validation: maxItems 100, maxLength 200
           - name: wixIntegrations | type: array<AppPlanIntegration> | description: Wix integrations the app uses, from Get App Planning Context. Empty when none.  | validation: maxItems 100
              - name: id | type: string | description: Integration GUID from Get App Planning Context, for example `wix-stores`.  | validation: maxLength 200
              - name: displayName | type: string | description: Display name. Replaced with the catalog's name.  | validation: maxLength 200
              - name: description | type: string | description: Why the app uses the integration.  | validation: maxLength 2000
              - name: tags | type: array<string> | description: Capabilities of the integration the app uses, for example `Cart & Checkout`.  | validation: maxItems 50, maxLength 100
   param name: planningContextId | type: planningContextId | description: `planningContextId` from Get App Planning Context. | required: true | validation: maxLength 100
   param name: proposalId | type: proposalId | description: GUID of a saved plan to change. When not specified, a new plan is saved.  | validation: format GUID
   param name: requestKey | type: requestKey | description: Stable key for this submission, created by the caller. Repeating a call with the same key and the same plan returns the same result. | required: true | validation: maxLength 100
   param name: schemaVersion | type: schemaVersion | description: `schemaVersion` from Get App Planning Context. | required: true | validation: maxLength 100
 Return type: SubmitAppPlanResponse
  - name: proposal | type: AppPlanProposal | description: The saved plan, normalized. Show this plan to the user for approval.  
     - name: id | type: string | description: Proposal GUID.  | validation: format GUID
     - name: revision | type: string | description: Revision of the plan. Increments by 1 each time the plan changes.  
     - name: digest | type: string | description: SHA-256 digest of the normalized plan, in hex. Specify it, with `revision`, when approving.  | validation: maxLength 64
     - name: plan | type: AppPlan | description: The normalized plan to show the user. This exact plan is built once approved.  
        - name: initialPrompt | type: string | description: The user's request, in their words. Not a technical implementation plan.  | validation: maxLength 10000
        - name: appSpec | type: AppPlanSpec | description: What the app does.  
           - name: appName | type: string | description: Display name of the app.  | validation: maxLength 200
           - name: appDescription | type: string | description: What users can do in the app.  | validation: maxLength 5000
           - name: businessGoal | type: string | description: The user outcome the app serves.  | validation: maxLength 2000
           - name: audience | type: string | description: The app's intended users, with any access assumptions.  | validation: maxLength 2000
           - name: features | type: array<AppPlanFeature> | description: Features of the app. At least one.  | validation: maxItems 200
              - name: title | type: string | description: Short feature title, unique in the plan.  | validation: maxLength 200
              - name: description | type: string | description: What the user does and gets, the content or data it uses, the access it needs and any significant limitation.  | validation: maxLength 2000
           - name: navigation | type: array<string> | description: Names of the app's screens, unique. At least one.  | validation: maxItems 100, maxLength 200
           - name: wixIntegrations | type: array<AppPlanIntegration> | description: Wix integrations the app uses, from Get App Planning Context. Empty when none.  | validation: maxItems 100
              - name: id | type: string | description: Integration GUID from Get App Planning Context, for example `wix-stores`.  | validation: maxLength 200
              - name: displayName | type: string | description: Display name. Replaced with the catalog's name.  | validation: maxLength 200
              - name: description | type: string | description: Why the app uses the integration.  | validation: maxLength 2000
              - name: tags | type: array<string> | description: Capabilities of the integration the app uses, for example `Cart & Checkout`.  | validation: maxItems 50, maxLength 100
     - name: status | type: AppPlanProposalStatus | description: Proposal status.  
         - enum:
         -     READY_FOR_APPROVAL: Ready for the user's approval.
         -     APPROVED: Approved. The plan can't change.
     - name: generationId | type: string | description: GUID of the app generation started from this plan. Returned once the plan is approved.  | validation: format GUID
     - name: expiresDate | type: string | description: Date and time the plan must be approved by, 24 hours after it's created.  | validation: format date-time

 Possible Errors:
   HTTP Code: 400 | Status Code: INVALID_ARGUMENT | Application Code: INVALID_APP_PLAN | Description: The plan has errors. `data.errors` lists each one with its field path.
   HTTP Code: 404 | Status Code: NOT_FOUND | Application Code: APP_PLAN_NOT_FOUND | Description: Couldn't find the app plan for the current user and site.
   HTTP Code: 409 | Status Code: ALREADY_EXISTS | Application Code: IDEMPOTENCY_CONFLICT | Description: `requestKey` was already used with a different plan.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: APP_PLAN_REVISION_LIMIT | Description: The plan reached its maximum of 50 revisions. Submit it as a new plan, without `proposalId`.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: APP_PLAN_ALREADY_APPROVED | Description: App plan was already approved. It can't change.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: CONTEXT_EXPIRED | Description: The planning context expired, or belongs to another user or site. Call Get App Planning Context again.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: UNSUPPORTED_SCHEMA_VERSION | Description: `schemaVersion` isn't supported. Call Get App Planning Context again.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: FEATURE_UNAVAILABLE | Description: App generation isn't available for this site.


```

### Examples

### Submit App Plan
Validates a mobile app plan and saves it for the user's approval.

```curl
curl -X POST \
'https://www.wixapis.com/containers/projects/v1/app-plans' \
-H 'Authorization: <AUTH>' \
-H 'Content-Type: application/json' \
-d '{
  "requestKey": "b7e3c1d9-4a2f-4e6b-8c05-1f9d7a3e6b24",
  "schemaVersion": "appsmith.mobile-plan.v1",
  "planningContextId": "5f1c9e2a-7b3d-3c41-9a8e-2d6f4b0c7e15",
  "catalogVersion": "c1-8e4f2a91b07c",
  "plan": {
    "initialPrompt": "I want an app where my customers can browse my coffee beans and order them for delivery.",
    "appSpec": {
      "appName": "Ridge Coffee Roasters",
      "appDescription": "Browse the current coffee bean selection, read tasting notes, and order beans for home delivery.",
      "businessGoal": "Let regular customers reorder their favorite beans in a few taps.",
      "audience": "Existing customers of the roastery. No sign-in is needed to browse; checkout uses the store's checkout.",
      "features": [
        {
          "title": "Bean catalog",
          "description": "Customers browse the store's coffee beans with photos, origin, and tasting notes."
        },
        {
          "title": "Order for delivery",
          "description": "Customers add beans to the cart and check out with the site's store checkout."
        }
      ],
      "navigation": [
        "Home",
        "Shop",
        "Cart"
      ],
      "wixIntegrations": [
        {
          "id": "wix-stores",
          "displayName": "Wix Stores",
          "description": "Shows the store's products and handles cart and checkout.",
          "tags": [
            "Products",
            "Cart & Checkout"
          ]
        }
      ]
    }
  }
}'
```

---

## JavaScript SDK

### Schema

```
 Method: wixClientAdmin.containers.projects.submitAppPlan(requestKey, options)
 Description: Validates a mobile app plan and saves it for approval.  Returns the normalized plan with its `revision` and `digest`. Show this plan to the user and, once they approve it, call [Approve App Generation](https://dev.wix.com/docs/api-reference/mobile/containers-app/containers-projects/project-v1/approve-app-generation.md) with the same `revision` and `digest`.  To change a saved plan, call this method again with `proposalId` and a new `requestKey`. Each change creates a new revision, and approval of an earlier revision is refused. A plan can have up to 50 revisions. A saved plan expires 24 hours after it's created, at `expiresDate`.  Repeating a call with the same `requestKey` and the same plan returns the same result.
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  requestKey, options.schemaVersion, options.planningContextId, options.catalogVersion, options.plan, options
 Method parameters: 
   param name: options | type: SubmitAppPlanOptions  none | required: true 
        - name: schemaVersion | type: string | description: `schemaVersion` from Get App Planning Context. | required: true | validation: maxLength 100
        - name: planningContextId | type: string | description: `planningContextId` from Get App Planning Context. | required: true | validation: maxLength 100
        - name: catalogVersion | type: string | description: `catalogVersion` from Get App Planning Context. | required: true | validation: maxLength 100
        - name: plan | type: AppPlan | description: The plan. | required: true 
           - name: initialPrompt | type: string | description: The user's request, in their words. Not a technical implementation plan.  | validation: maxLength 10000
           - name: appSpec | type: AppPlanSpec | description: What the app does.  
              - name: appName | type: string | description: Display name of the app.  | validation: maxLength 200
              - name: appDescription | type: string | description: What users can do in the app.  | validation: maxLength 5000
              - name: businessGoal | type: string | description: The user outcome the app serves.  | validation: maxLength 2000
              - name: audience | type: string | description: The app's intended users, with any access assumptions.  | validation: maxLength 2000
              - name: features | type: array<AppPlanFeature> | description: Features of the app. At least one.  | validation: maxItems 200
                 - name: title | type: string | description: Short feature title, unique in the plan.  | validation: maxLength 200
                 - name: description | type: string | description: What the user does and gets, the content or data it uses, the access it needs and any significant limitation.  | validation: maxLength 2000
              - name: navigation | type: array<string> | description: Names of the app's screens, unique. At least one.  | validation: maxItems 100, maxLength 200
              - name: wixIntegrations | type: array<AppPlanIntegration> | description: Wix integrations the app uses, from Get App Planning Context. Empty when none.  | validation: maxItems 100
                 - name: _id | type: string | description: Integration GUID from Get App Planning Context, for example `wix-stores`.  | validation: maxLength 200
                 - name: displayName | type: string | description: Display name. Replaced with the catalog's name.  | validation: maxLength 200
                 - name: description | type: string | description: Why the app uses the integration.  | validation: maxLength 2000
                 - name: tags | type: array<string> | description: Capabilities of the integration the app uses, for example `Cart & Checkout`.  | validation: maxItems 50, maxLength 100
        - name: proposalId | type: string | description: GUID of a saved plan to change. When not specified, a new plan is saved.  | validation: format GUID
   param name: requestKey | type: string | description: Stable key for this submission, created by the caller. Repeating a call with the same key and the same plan returns the same result. | required: true | validation: maxLength 100
 Return type: PROMISE<SubmitAppPlanResponse>
  - name: proposal | type: AppPlanProposal | description: The saved plan, normalized. Show this plan to the user for approval.  
     - name: _id | type: string | description: Proposal GUID.  | validation: format GUID
     - name: revision | type: string | description: Revision of the plan. Increments by 1 each time the plan changes.  
     - name: digest | type: string | description: SHA-256 digest of the normalized plan, in hex. Specify it, with `revision`, when approving.  | validation: maxLength 64
     - name: plan | type: AppPlan | description: The normalized plan to show the user. This exact plan is built once approved.  
        - name: initialPrompt | type: string | description: The user's request, in their words. Not a technical implementation plan.  | validation: maxLength 10000
        - name: appSpec | type: AppPlanSpec | description: What the app does.  
           - name: appName | type: string | description: Display name of the app.  | validation: maxLength 200
           - name: appDescription | type: string | description: What users can do in the app.  | validation: maxLength 5000
           - name: businessGoal | type: string | description: The user outcome the app serves.  | validation: maxLength 2000
           - name: audience | type: string | description: The app's intended users, with any access assumptions.  | validation: maxLength 2000
           - name: features | type: array<AppPlanFeature> | description: Features of the app. At least one.  | validation: maxItems 200
              - name: title | type: string | description: Short feature title, unique in the plan.  | validation: maxLength 200
              - name: description | type: string | description: What the user does and gets, the content or data it uses, the access it needs and any significant limitation.  | validation: maxLength 2000
           - name: navigation | type: array<string> | description: Names of the app's screens, unique. At least one.  | validation: maxItems 100, maxLength 200
           - name: wixIntegrations | type: array<AppPlanIntegration> | description: Wix integrations the app uses, from Get App Planning Context. Empty when none.  | validation: maxItems 100
              - name: _id | type: string | description: Integration GUID from Get App Planning Context, for example `wix-stores`.  | validation: maxLength 200
              - name: displayName | type: string | description: Display name. Replaced with the catalog's name.  | validation: maxLength 200
              - name: description | type: string | description: Why the app uses the integration.  | validation: maxLength 2000
              - name: tags | type: array<string> | description: Capabilities of the integration the app uses, for example `Cart & Checkout`.  | validation: maxItems 50, maxLength 100
     - name: status | type: AppPlanProposalStatus | description: Proposal status.  
         - enum:
         -     READY_FOR_APPROVAL: Ready for the user's approval.
         -     APPROVED: Approved. The plan can't change.
     - name: generationId | type: string | description: GUID of the app generation started from this plan. Returned once the plan is approved.  | validation: format GUID
     - name: expiresDate | type: Date | description: Date and time the plan must be approved by, 24 hours after it's created.  

 Possible Errors:
   HTTP Code: 400 | Status Code: INVALID_ARGUMENT | Application Code: INVALID_APP_PLAN | Description: The plan has errors. `data.errors` lists each one with its field path.
   HTTP Code: 404 | Status Code: NOT_FOUND | Application Code: APP_PLAN_NOT_FOUND | Description: Couldn't find the app plan for the current user and site.
   HTTP Code: 409 | Status Code: ALREADY_EXISTS | Application Code: IDEMPOTENCY_CONFLICT | Description: `requestKey` was already used with a different plan.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: APP_PLAN_REVISION_LIMIT | Description: The plan reached its maximum of 50 revisions. Submit it as a new plan, without `proposalId`.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: APP_PLAN_ALREADY_APPROVED | Description: App plan was already approved. It can't change.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: CONTEXT_EXPIRED | Description: The planning context expired, or belongs to another user or site. Call Get App Planning Context again.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: UNSUPPORTED_SCHEMA_VERSION | Description: `schemaVersion` isn't supported. Call Get App Planning Context again.
   HTTP Code: 428 | Status Code: FAILED_PRECONDITION | Application Code: FEATURE_UNAVAILABLE | Description: App generation isn't available for this site.


```

### Examples

### Submit a mobile app plan
Validates the plan and saves it for the user's approval.

```javascript
import { projects } from "@wix/containers";

async function submitAppPlan() {
  const response = await projects.submitAppPlan(
    "b7e3c1d9-4a2f-4e6b-8c05-1f9d7a3e6b24",
    {
      schemaVersion: "appsmith.mobile-plan.v1",
      planningContextId: "5f1c9e2a-7b3d-3c41-9a8e-2d6f4b0c7e15",
      catalogVersion: "c1-8e4f2a91b07c",
      plan: {
        initialPrompt:
          "I want an app where my customers can browse my coffee beans and order them for delivery.",
        appSpec: {
          appName: "Ridge Coffee Roasters",
          appDescription:
            "Browse the current coffee bean selection, read tasting notes, and order beans for home delivery.",
          businessGoal: "Let regular customers reorder their favorite beans in a few taps.",
          audience:
            "Existing customers of the roastery. No sign-in is needed to browse; checkout uses the store's checkout.",
          features: [
            {
              title: "Bean catalog",
              description:
                "Customers browse the store's coffee beans with photos, origin, and tasting notes.",
            },
            {
              title: "Order for delivery",
              description:
                "Customers add beans to the cart and check out with the site's store checkout.",
            },
          ],
          navigation: ["Home", "Shop", "Cart"],
          wixIntegrations: [
            {
              _id: "wix-stores",
              displayName: "Wix Stores",
              description: "Shows the store's products and handles cart and checkout.",
              tags: ["Products", "Cart & Checkout"],
            },
          ],
        },
      },
    },
  );
}

/* Promise resolves to:
 * {
 *   "proposal": {
 *     "_id": "3e8b6d2f-91a4-4c7e-b5d0-6f2a8c1e9b47",
 *     "revision": "1",
 *     "digest": "4f9a2c7e1b8d3a6f0e5c9b2d7a4e1f8c3b6d0a9e2f7c4b1d8a5e3f6c9b0d2a7e",
 *     "plan": {
 *       "initialPrompt": "I want an app where my customers can browse my coffee beans and order them for delivery.",
 *       "appSpec": {
 *         "appName": "Ridge Coffee Roasters",
 *         "appDescription": "Browse the current coffee bean selection, read tasting notes, and order beans for home delivery.",
 *         "businessGoal": "Let regular customers reorder their favorite beans in a few taps.",
 *         "audience": "Existing customers of the roastery. No sign-in is needed to browse; checkout uses the store's checkout.",
 *         "features": [
 *           {
 *             "title": "Bean catalog",
 *             "description": "Customers browse the store's coffee beans with photos, origin, and tasting notes."
 *           },
 *           {
 *             "title": "Order for delivery",
 *             "description": "Customers add beans to the cart and check out with the site's store checkout."
 *           }
 *         ],
 *         "navigation": ["Home", "Shop", "Cart"],
 *         "wixIntegrations": [
 *           {
 *             "_id": "wix-stores",
 *             "displayName": "Wix Stores",
 *             "description": "Shows the store's products and handles cart and checkout.",
 *             "tags": ["Products", "Cart & Checkout"]
 *           }
 *         ]
 *       }
 *     },
 *     "status": "READY_FOR_APPROVAL",
 *     "expiresDate": "2026-11-10T09:30:00.000Z"
 *   }
 * }
 */

```

### submitAppPlan (self-managed)
Self-managed SDK calls require you to [create a client](https://dev.wix.com/docs/sdk/articles/work-with-the-sdk/about-the-wix-client.md).

```javascript
import { createClient } from '@wix/sdk';
import { projects } from '@wix/containers';
// Import the auth strategy for the relevant access type
// Import the relevant host module if needed

const myWixClient = createClient ({
  modules: { projects },
  // Include the auth strategy and host as relevant
});


async function submitAppPlan(requestKey,options) {
  const response = await myWixClient.projects.submitAppPlan(requestKey,options);
};
```

---