---
title: "Generate SOW from user stories"
description: "Use AI to generate a Statement of Work structure from selected user stories"
---

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

Path: Test And Accept API › UserStories

`POST /user-stories/generate-sow`

Use AI to generate a Statement of Work structure from selected user stories

## Authentication

- `bearerAuth`, http, header `Authorization`, format `tnda_ token`

## Request body

_Required._

- `storyIds` (`userStories-generateSowFromStories.storyIds`; array<string>, required)
  - format `uuid`; pattern `^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$`
- `projectId` (`userStories-generateSowFromStories.projectId`; string, required)
  - format `uuid`; pattern `^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$`
- `generateTests` (`userStories-generateSowFromStories.generateTests`; boolean, optional)
  - default `true`
- `organizationStyle` (`userStories-generateSowFromStories.organizationStyle`; string, optional)
  - one of `"hierarchical"`, `"flat"`, `"feature-based"`; default `"hierarchical"`

## Example request

```json
{
  "storyIds": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
  "generateTests": true,
  "organizationStyle": "hierarchical"
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://api.testandaccept.com/api/rest/user-stories/generate-sow \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "storyIds": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
  "generateTests": true,
  "organizationStyle": "hierarchical"
}
'
```

### TypeScript

```typescript
const url = 'https://api.testandaccept.com/api/rest/user-stories/generate-sow';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', Authorization: 'Bearer <token>'},
  body: JSON.stringify({
    storyIds: ['497f6eca-6276-4993-bfeb-53cbbbba6f08'],
    projectId: '5a8591dd-4039-49df-9202-96385ba3eff8',
    generateTests: true,
    organizationStyle: 'hierarchical'
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://api.testandaccept.com/api/rest/user-stories/generate-sow"

payload = {
    "storyIds": ["497f6eca-6276-4993-bfeb-53cbbbba6f08"],
    "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
    "generateTests": True,
    "organizationStyle": "hierarchical"
}
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <token>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

Successful response

#### Example

```json
{
  "sowProposal": {
    "title": "string",
    "description": "string"
  },
  "taskProposals": [
    {
      "title": "string",
      "description": "string",
      "type": "requirement",
      "priority": "low",
      "acceptanceCriteria": [
        "string"
      ],
      "linkedStepIds": [
        "string"
      ]
    }
  ],
  "stepMappings": [
    {
      "stepId": "string",
      "taskIndex": 0
    }
  ],
  "coverageAnalysis": {
    "storiesCovered": 0,
    "coveragePercentage": 0,
    "gaps": [
      "string"
    ]
  }
}
```

- `sowProposal` (`userStories-generateSowFromStories.response.200.sowProposal`; object, required)
  - `title` (`userStories-generateSowFromStories.response.200.sowProposal.title`; string, required)
  - `description` (`userStories-generateSowFromStories.response.200.sowProposal.description`; string, required)
- `taskProposals` (`userStories-generateSowFromStories.response.200.taskProposals`; array<object>, required)
  - `title` (`userStories-generateSowFromStories.response.200.taskProposals.title`; string, required)
  - `description` (`userStories-generateSowFromStories.response.200.taskProposals.description`; string, required)
  - `type` (`userStories-generateSowFromStories.response.200.taskProposals.type`; string, required)
    - one of `"requirement"`, `"task_item"`, `"milestone"`, `"deliverable"`
  - `priority` (`userStories-generateSowFromStories.response.200.taskProposals.priority`; string, required)
    - one of `"low"`, `"medium"`, `"high"`, `"critical"`
  - `acceptanceCriteria` (`userStories-generateSowFromStories.response.200.taskProposals.acceptanceCriteria`; array<string>, optional)
  - `linkedStepIds` (`userStories-generateSowFromStories.response.200.taskProposals.linkedStepIds`; array<string>, optional)
- `stepMappings` (`userStories-generateSowFromStories.response.200.stepMappings`; array<object>, required)
  - `stepId` (`userStories-generateSowFromStories.response.200.stepMappings.stepId`; string, required)
  - `taskIndex` (`userStories-generateSowFromStories.response.200.stepMappings.taskIndex`; number, required)
- `coverageAnalysis` (`userStories-generateSowFromStories.response.200.coverageAnalysis`; object, required)
  - `storiesCovered` (`userStories-generateSowFromStories.response.200.coverageAnalysis.storiesCovered`; number, required)
  - `coveragePercentage` (`userStories-generateSowFromStories.response.200.coverageAnalysis.coveragePercentage`; number, required)
  - `gaps` (`userStories-generateSowFromStories.response.200.coverageAnalysis.gaps`; array<string>, required)

### 400

Invalid input data

#### Example

```json
{
  "code": "BAD_REQUEST",
  "message": "Invalid input data",
  "issues": []
}
```

- `message` (`userStories-generateSowFromStories.response.400.message`; string, required) — The error message
  - example `"Invalid input data"`
- `code` (`userStories-generateSowFromStories.response.400.code`; string, required) — The error code
  - example `"BAD_REQUEST"`
- `issues` (`userStories-generateSowFromStories.response.400.issues`; array<object>, optional) — An array of issues that were responsible for the error
  - example `[]`
  - `message` (`userStories-generateSowFromStories.response.400.issues.message`; string, required)

### 401

Authorization not provided

#### Example

```json
{
  "code": "UNAUTHORIZED",
  "message": "Authorization not provided",
  "issues": []
}
```

- `message` (`userStories-generateSowFromStories.response.401.message`; string, required) — The error message
  - example `"Authorization not provided"`
- `code` (`userStories-generateSowFromStories.response.401.code`; string, required) — The error code
  - example `"UNAUTHORIZED"`
- `issues` (`userStories-generateSowFromStories.response.401.issues`; array<object>, optional) — An array of issues that were responsible for the error
  - example `[]`
  - `message` (`userStories-generateSowFromStories.response.401.issues.message`; string, required)

### 403

Insufficient access

#### Example

```json
{
  "code": "FORBIDDEN",
  "message": "Insufficient access",
  "issues": []
}
```

- `message` (`userStories-generateSowFromStories.response.403.message`; string, required) — The error message
  - example `"Insufficient access"`
- `code` (`userStories-generateSowFromStories.response.403.code`; string, required) — The error code
  - example `"FORBIDDEN"`
- `issues` (`userStories-generateSowFromStories.response.403.issues`; array<object>, optional) — An array of issues that were responsible for the error
  - example `[]`
  - `message` (`userStories-generateSowFromStories.response.403.issues.message`; string, required)

### 500

Internal server error

#### Example

```json
{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}
```

- `message` (`userStories-generateSowFromStories.response.500.message`; string, required) — The error message
  - example `"Internal server error"`
- `code` (`userStories-generateSowFromStories.response.500.code`; string, required) — The error code
  - example `"INTERNAL_SERVER_ERROR"`
- `issues` (`userStories-generateSowFromStories.response.500.issues`; array<object>, optional) — An array of issues that were responsible for the error
  - example `[]`
  - `message` (`userStories-generateSowFromStories.response.500.issues.message`; string, required)


Source: https://docs.testandaccept.com/reference/user-stories/generate-sow-from-stories/index.md
