> ## Documentation Index
> Fetch the complete documentation index at: https://alliancebioversityciat-alliance-risk-analysis-tool.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Document operations

Upload documents, trigger parsing, and manage other assessment operations.

## Request upload URL

```bash cURL theme={null}
curl -X POST https://api.example.com/api/assessments/550e8400-e29b-41d4-a716-446655440000/documents \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "financial-statements.pdf",
    "mimeType": "application/pdf",
    "fileSize": 2457600
  }'
```

```javascript JavaScript theme={null}
const assessmentId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.example.com/api/assessments/${assessmentId}/documents`,
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      fileName: 'financial-statements.pdf',
      mimeType: 'application/pdf',
      fileSize: 2457600
    })
  }
);

const { presignedUrl, documentId } = await response.json();
```

### Endpoint

`POST /api/assessments/:id/documents`

### Path parameters

**id** `string` *required*

Assessment ID (UUID).

### Request body

**fileName** `string` *required*

Name of the file to upload.

Maximum length: 255 characters.

**mimeType** `string` *required*

MIME type of the file.

Currently only `application/pdf` is supported. Maximum length: 50 characters.

**fileSize** `number` *required*

File size in bytes.

Maximum: 26,214,400 bytes (25 MB).

### Response

**presignedUrl** `string`

Pre-signed S3 URL for uploading the file. Valid for 15 minutes.

**documentId** `string`

Unique document identifier (UUID). Use this to trigger parsing after upload.

### Upload workflow

**1. Request upload URL**

POST to `/api/assessments/:id/documents` with file metadata.

**2. Upload file to S3**

PUT the file to the `presignedUrl` using the exact `mimeType` from your request.

```bash theme={null}
curl -X PUT "$PRESIGNED_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @financial-statements.pdf
```

**3. Trigger parsing**

POST to `/api/assessments/:id/documents/:documentId/parse` to start AI document analysis.

> [!WARNING]
>
> The presigned URL expires after 15 minutes. If upload fails, request a new URL.

***

## Trigger document parsing

```bash cURL theme={null}
curl -X POST https://api.example.com/api/assessments/550e8400-e29b-41d4-a716-446655440000/documents/abc123/parse \
  -H "Authorization: Bearer YOUR_TOKEN"
```

```javascript JavaScript theme={null}
const assessmentId = '550e8400-e29b-41d4-a716-446655440000';
const documentId = 'abc123';

const response = await fetch(
  `https://api.example.com/api/assessments/${assessmentId}/documents/${documentId}/parse`,
  {
    method: 'POST',
    headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
  }
);

const jobId = await response.json();

// Poll job status
const pollJob = async (jobId) => {
  const jobResponse = await fetch(
    `https://api.example.com/api/jobs/${jobId}`,
    { headers: { 'Authorization': 'Bearer YOUR_TOKEN' } }
  );
  const job = await jobResponse.json();
  
  if (job.status === 'COMPLETED') {
    console.log('Parsing complete:', job.result);
  } else if (job.status === 'FAILED') {
    console.error('Parsing failed:', job.error);
  } else {
    // Still processing, poll again
    setTimeout(() => pollJob(jobId), 2000);
  }
};

pollJob(jobId);
```

### Endpoint

`POST /api/assessments/:id/documents/:documentId/parse`

Starts an asynchronous job to parse the uploaded document using AWS Bedrock AI models.

### Path parameters

**id** `string` *required*

Assessment ID (UUID).

**documentId** `string` *required*

Document ID returned from the upload URL request.

### Response

Returns a job ID (string) to poll for completion status.

```json theme={null}
"job-uuid-here"
```

### Job polling

Use `GET /api/jobs/:id` to check the parsing status:

* `PENDING` - Job is queued
* `PROCESSING` - AI is analyzing the document
* `COMPLETED` - Parsing finished successfully
* `FAILED` - Parsing failed (check `error` field)

Poll every 2-5 seconds until the job reaches a terminal state.

> [!NOTE]
>
> When parsing starts, the assessment status automatically changes to `ANALYZING`.

***

## Add comment

```bash cURL theme={null}
curl -X POST https://api.example.com/api/assessments/550e8400-e29b-41d4-a716-446655440000/comments \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Reviewed financial statements - revenue projections look strong."
  }'
```

```javascript JavaScript theme={null}
const assessmentId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.example.com/api/assessments/${assessmentId}/comments`,
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      content: 'Reviewed financial statements - revenue projections look strong.'
    })
  }
);

const comment = await response.json();
```

### Endpoint

`POST /api/assessments/:id/comments`

### Path parameters

**id** `string` *required*

Assessment ID (UUID).

### Request body

**content** `string` *required*

Comment text.

Maximum length: 2000 characters.

### Response

**id** `string`

Comment ID (UUID).

**assessmentId** `string`

Assessment ID this comment belongs to.

**userId** `string`

ID of the user who created the comment.

**content** `string`

Comment text.

**createdAt** `string`

ISO 8601 timestamp of creation.

***

## Get comments

```bash cURL theme={null}
curl -X GET https://api.example.com/api/assessments/550e8400-e29b-41d4-a716-446655440000/comments \
  -H "Authorization: Bearer YOUR_TOKEN"
```

```javascript JavaScript theme={null}
const assessmentId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.example.com/api/assessments/${assessmentId}/comments`,
  {
    headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
  }
);

const comments = await response.json();
```

### Endpoint

`GET /api/assessments/:id/comments`

Retrieve all comments for an assessment, ordered chronologically.

### Path parameters

**id** `string` *required*

Assessment ID (UUID).

### Response

Returns an array of comment objects with user information.

**comments** `array`

**Comment properties**

**id** `string`

Comment ID (UUID).

**assessmentId** `string`

Assessment ID.

**userId** `string`

Comment author ID.

**content** `string`

Comment text.

**createdAt** `string`

ISO 8601 creation timestamp.

**user** `object`

User information.

**User properties**

**email** `string`

Author's email address.

### Example response

```json theme={null}
[
  {
    "id": "comment-uuid-1",
    "assessmentId": "550e8400-e29b-41d4-a716-446655440000",
    "userId": "auth0|123456789",
    "content": "Reviewed financial statements - revenue projections look strong.",
    "createdAt": "2026-03-04T12:00:00.000Z",
    "user": {
      "email": "analyst@example.com"
    }
  },
  {
    "id": "comment-uuid-2",
    "assessmentId": "550e8400-e29b-41d4-a716-446655440000",
    "userId": "auth0|987654321",
    "content": "Flagged climate risks for further investigation.",
    "createdAt": "2026-03-04T14:30:00.000Z",
    "user": {
      "email": "reviewer@example.com"
    }
  }
]
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.