> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portal.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate an AI Outline for a Proposal

> POST .../ai/outline — Starts async AI outline generation from uploaded content. Returns proposalId and initial status. Requires transcribed content.

Starts asynchronous AI outline generation for the specified proposal. The proposal must contain transcribed project spec content or media transcripts — if no qualifying content is present, the request returns a `400` error. Once triggered, use [Get Proposal Outline](/api-reference/ai-builder/get-outline) to check progress or listen for the `Proposal Outline Status Changed` webhook.

<Note>
  Outline generation is asynchronous. The `200` response confirms the job has been queued, but the outline will not be available immediately. Poll [Get Proposal Outline](/api-reference/ai-builder/get-outline) and check for `status: "Completed"`, or subscribe to the `Proposal Outline Status Changed` webhook.
</Note>

<RequestExample>
  ```bash curl theme={null}
  curl -i -X POST \
    'https://api.portal.io/public/proposals/12345/ai/outline' \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -H 'X-MSS-API-APPID: YOUR_API_APPID' \
    -H 'X-MSS-API-USERKEY: YOUR_API_USERKEY' \
    -H 'X-MSS-CUSTOM-DATE: Thu, 17 Apr 2026 12:00:00 GMT' \
    -H 'X-MSS-SIGNATURE: Base64EncodedHMACSHA256Signature' \
    -d '{"proposalId": 12345}'
  ```

  ```python python theme={null}
  import requests
  from portal_auth import sign_request

  url = "https://api.portal.io/public/proposals/12345/ai/outline"
  timestamp = "Mon, 06 Apr 2026 00:22:19 GMT"
  content_type = "application/json"
  signature = sign_request("POST", url, content_type, timestamp, "YOUR_USER_KEY", "YOUR_SECRET_KEY")

  response = requests.post(url, headers={
      "Accept": "application/json",
      "Content-Type": content_type,
      "X-MSS-API-APPID": "YOUR_APP_ID",
      "X-MSS-API-USERKEY": "YOUR_USER_KEY",
      "X-MSS-CUSTOM-DATE": timestamp,
      "X-MSS-SIGNATURE": signature
  }, json={
      "proposalId": 12345
  })
  print(response.json())
  ```

  ```javascript node.js theme={null}
  const { signRequest } = require('./portalAuth');

  const url = "https://api.portal.io/public/proposals/12345/ai/outline";
  const timestamp = new Date().toUTCString();
  const contentType = "application/json";
  const signature = signRequest("POST", url, contentType, timestamp, "YOUR_USER_KEY", "YOUR_SECRET_KEY");

  const response = await fetch(url, {
      method: "POST",
      headers: {
          "Accept": "application/json",
          "Content-Type": contentType,
          "X-MSS-API-APPID": "YOUR_APP_ID",
          "X-MSS-API-USERKEY": "YOUR_USER_KEY",
          "X-MSS-CUSTOM-DATE": timestamp,
          "X-MSS-SIGNATURE": signature
      },
      body: JSON.stringify({ proposalId: 12345 })
  });
  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

```json Response theme={null}
{
  "proposalId": 12345,
  "status": "Generating"
}
```


## OpenAPI

````yaml POST /public/proposals/{ProposalId}/ai/outline
openapi: 3.1.0
info:
  title: Portal.Api
  version: '1.0'
servers:
  - url: http://127.0.0.1:5000
security: []
tags: []
paths:
  /public/proposals/{ProposalId}/ai/outline:
    post:
      tags:
        - Proposal AI Builder
      summary: Generate Proposal Outline
      description: Start asynchronous AI outline generation for a proposal.
      operationId: GenerateAiProposalOutline
      parameters:
        - $ref: '#/components/parameters/Accept'
        - name: X-MSS-API-APPID
          in: header
          description: Application Id
          required: true
          schema:
            type: string
        - name: X-MSS-CUSTOM-DATE
          in: header
          description: A date timestamp of the request
          required: true
          schema:
            type: string
        - name: X-MSS-SIGNATURE
          in: header
          description: A signature for the request
          required: true
          schema:
            type: string
        - name: X-MSS-API-USERKEY
          in: header
          description: User API Key
          required: true
          schema:
            type: string
        - name: ProposalId
          in: path
          description: >-
            Proposal identifier. Must be a positive integer corresponding to an
            existing proposal. The proposal should contain transcribed project
            spec content or media transcripts; otherwise the request will be
            rejected with a 400 Bad Request.
          required: true
          x-nullable: false
          schema:
            type: integer
            format: int32
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicAiProposalOutlinePostRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicAiProposalOutlinePostResponse'
        '400':
          description: >-
            Bad Request: the specified proposal does not contain the transcribed
            media or project specification content required for AI outline
            generation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: >-
            Not Authorized to access this endpoint or your HMAC hash was
            incorrect.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebServiceException'
        '403':
          description: You do not have permission for this API call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '404':
          description: Proposal not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
      deprecated: false
      x-codeSamples: []
components:
  parameters:
    Accept:
      name: Accept
      in: header
      description: Accept Header
      required: true
      schema:
        type: string
        enum:
          - application/json
  schemas:
    PublicAiProposalOutlinePostRequest:
      title: PublicAiProposalOutlinePostRequest
      required:
        - proposalId
      properties:
        proposalId:
          description: >-
            Proposal identifier. Must be a positive integer corresponding to an
            existing proposal. The proposal should contain transcribed project
            spec content or media transcripts; otherwise the request will be
            rejected with a 400 Bad Request.
          type: integer
          format: int32
      description: Proposals Service
      type: object
    PublicAiProposalOutlinePostResponse:
      title: PublicAiProposalOutlinePostResponse
      required:
        - proposalId
        - status
      properties:
        proposalId:
          description: >-
            ID of the proposal for which outline generation was triggered. Use
            this value to correlate asynchronous job progress and final outline
            results.
          type: integer
          format: int32
        status:
          description: >-
            Current status of the outline generation job. Consumers should poll
            or listen to webhooks to get final completed output when status
            becomes Completed.
          type: string
      description: PublicAiProposalOutlinePostResponse
      type: object
    HttpError:
      title: HttpError
      properties:
        errorCode:
          type: string
        stackTrace:
          type: string
        contentType:
          type: string
        headers:
          $ref: '#/components/schemas/Dictionary_String_String_'
        cookies:
          type: array
          items:
            $ref: '#/components/schemas/Cookie'
        status:
          type: integer
          format: int32
        statusCode:
          type: string
        statusDescription:
          type: string
        response:
          $ref: '#/components/schemas/Object'
        responseFilter:
          $ref: '#/components/schemas/IContentTypeWriter'
        requestContext:
          $ref: '#/components/schemas/IRequest'
        paddingLength:
          type: integer
          format: int32
        resultScope:
          $ref: '#/components/schemas/Func_IDisposable_'
        options:
          $ref: '#/components/schemas/IDictionary_String_String_'
        responseStatus:
          $ref: '#/components/schemas/ResponseStatus'
        targetSite:
          $ref: '#/components/schemas/MethodBase'
        message:
          type: string
        data:
          $ref: '#/components/schemas/IDictionary'
        innerException:
          $ref: '#/components/schemas/Exception'
        helpLink:
          type: string
        source:
          type: string
        hResult:
          type: integer
          format: int32
      description: HttpError
      type: object
    WebServiceException:
      title: WebServiceException
      properties:
        statusCode:
          type: integer
          format: int32
        statusDescription:
          type: string
        responseHeaders:
          $ref: '#/components/schemas/WebHeaderCollection'
        responseDto:
          $ref: '#/components/schemas/Object'
        responseBody:
          type: string
        message:
          type: string
        errorCode:
          type: string
        errorMessage:
          type: string
        serverStackTrace:
          type: string
        state:
          $ref: '#/components/schemas/Object'
        responseStatus:
          $ref: '#/components/schemas/ResponseStatus'
        targetSite:
          $ref: '#/components/schemas/MethodBase'
        data:
          $ref: '#/components/schemas/IDictionary'
        innerException:
          $ref: '#/components/schemas/Exception'
        helpLink:
          type: string
        source:
          type: string
        hResult:
          type: integer
          format: int32
        stackTrace:
          type: string
      description: WebServiceException
      type: object
    Dictionary_String_String_:
      title: Dictionary<String,String>
      additionalProperties:
        type: string
      description: Dictionary<String,String>
      type: object
    Cookie:
      title: Cookie
      properties: {}
      description: Cookie
      type: object
    Object:
      properties: {}
      description: Object
      type: object
    IContentTypeWriter:
      title: IContentTypeWriter
      properties: {}
      description: IContentTypeWriter
      type: object
    IRequest:
      title: IRequest
      properties: {}
      description: IRequest
      type: object
    Func_IDisposable_:
      title: Func`1
      properties: {}
      description: Func<IDisposable>
      type: object
    IDictionary_String_String_:
      title: IDictionary<String,String>
      additionalProperties:
        type: string
      description: IDictionary<String,String>
      type: object
    ResponseStatus:
      title: ResponseStatus
      properties:
        errorCode:
          type: string
        message:
          type: string
        stackTrace:
          type: string
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ResponseError'
        meta:
          $ref: '#/components/schemas/Dictionary_String_String_'
      description: ResponseStatus
      type: object
    MethodBase:
      title: MethodBase
      properties: {}
      description: MethodBase
      type: object
    IDictionary:
      title: IDictionary
      properties: {}
      description: IDictionary
      type: object
    Exception:
      title: Exception
      properties: {}
      description: Exception
      type: object
    WebHeaderCollection:
      title: WebHeaderCollection
      properties: {}
      description: WebHeaderCollection
      type: object
    ResponseError:
      title: ResponseError
      properties:
        errorCode:
          type: string
        fieldName:
          type: string
        message:
          type: string
        meta:
          $ref: '#/components/schemas/Dictionary_String_String_'
      description: ResponseError
      type: object

````