# AMS Student and UHS-DTS API Integration

This document explains how AMS Student and UHS-DTS exchange student document request data.

## Overview

The integration has two directions:

1. AMS Student submits a student document request to DTS.
2. DTS updates the request status back to AMS Student when the workflow changes.

## Base URLs

AMS Student:

```text
https://student.datacolabx.com
```

UHS-DTS:

```text
https://dts.datacolabx.com
```

## Authentication

AMS Student must send the shared API key when calling DTS.

Required headers:

```http
Accept: application/json
Content-Type: application/json
X-External-Api-Key: <shared-api-key>
```

## 1. List DTS Document Types

AMS Student should call this endpoint to get the DTS document types that students are allowed to request.

```http
GET https://dts.datacolabx.com/api/external/student/document-types
```

Example:

```bash
curl -X GET "https://dts.datacolabx.com/api/external/student/document-types" \
  -H "Accept: application/json" \
  -H "X-External-Api-Key: <shared-api-key>"
```

Success response:

```json
{
  "success": true,
  "data": [
    {
      "id": 10,
      "name_en": "Academic Transcript",
      "name_kh": "Khmer document type name"
    }
  ]
}
```

Use the returned `id` as `document_type` when submitting a request to DTS.

## 2. Submit Student Request to DTS

AMS Student calls this endpoint for both single and multiple document requests. The body always contains a `requests` array; use one array item for a single document.

```http
POST https://dts.datacolabx.com/api/external/student/document-requests
```

Required request fields:

| Field | Type | Description |
| --- | --- | --- |
| `document_name` | string | Request title or document name. |
| `document_code` | string | AMS Student visible request code, for example `UHS75`. |
| `external_entry` | integer | AMS Student database row ID, for example `75`. DTS uses this to sync status back. |
| `document_path` | string | Main PDF/file URL from AMS Student. DTS downloads and validates the file during submission, then stores it in local requester storage. |
| `document_type` | integer | DTS document type ID from the document-types endpoint. |

Optional request fields:

| Field | Type | Description |
| --- | --- | --- |
| `description` | string | Extra note or description. |
| `supporting_files` | array | Extra file URLs. |

Single-document request body:

```json
{
  "requests": [
    {
      "document_name": "Academic Transcript Request",
      "document_code": "UHS75",
      "external_entry": 75,
      "document_path": "https://student.datacolabx.com/storage/document-requests/pdf-files/request-document-75-km.pdf",
      "document_type": 10,
      "description": "Submitted from AMS Student.",
      "supporting_files": [
        "https://student.datacolabx.com/storage/document-requests/pdf-files/request-document-75-km.pdf"
      ]
    }
  ]
}
```

Example:

```bash
curl -X POST "https://dts.datacolabx.com/api/external/student/document-requests" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-External-Api-Key: <shared-api-key>" \
  -d '{
    "requests": [
      {
        "document_name": "Academic Transcript Request",
        "document_code": "UHS75",
        "external_entry": 75,
        "document_path": "https://student.datacolabx.com/storage/document-requests/pdf-files/request-document-75-km.pdf",
        "document_type": 10,
        "description": "Submitted from AMS Student.",
        "supporting_files": [
          "https://student.datacolabx.com/storage/document-requests/pdf-files/request-document-75-km.pdf"
        ]
      }
    ]
  }'
```

Success response:

```json
{
  "success": true,
  "message": "Document requests submitted successfully.",
  "summary": {
    "total": 1,
    "created": 1,
    "idempotent": 0,
    "failed": 0
  },
  "data": [
    {
      "index": 0,
      "external_entry": 75,
      "success": true,
      "status": 201,
      "idempotent": false,
      "data": {
        "id": 125,
        "external_entry": 75,
        "document_code": "UHS75",
        "uhs_code": "2026-0042",
        "status": "submit",
        "public_tracking_token": "c0f1...",
        "created_at": "2026-07-10T08:12:30.000000Z"
      }
    }
  ]
}
```

Response field notes:

| Field | Description |
| --- | --- |
| `id` | DTS internal request ID. |
| `external_entry` | AMS Student request row ID used for status sync and idempotent retries. |
| `document_code` | AMS Student visible request code. |
| `uhs_code` | DTS generated tracking code. |
| `public_tracking_token` | Token for the public tracking page. |

## 3. Submit Multiple Student Requests

Use the same endpoint with more than one array item. Each item creates an independent DTS request with its own workflow, status, tracking token, and UHS code.

```http
POST https://dts.datacolabx.com/api/external/student/document-requests
```

The request accepts between 1 and 50 items. `external_entry` is required and uniquely identifies one AMS document request. If the same `external_entry` is submitted again, DTS returns the existing request instead of creating a duplicate.

```json
{
  "requests": [
    {
      "document_name": "Academic Transcript Request",
      "document_code": "UHS75",
      "external_entry": 75,
      "document_path": "https://student.datacolabx.com/storage/document-requests/transcript-75.pdf",
      "document_type": 10
    },
    {
      "document_name": "Study Certificate Request",
      "document_code": "UHS76",
      "external_entry": 76,
      "document_path": "https://student.datacolabx.com/storage/document-requests/certificate-76.pdf",
      "document_type": 12
    }
  ]
}
```

A fully successful new batch returns HTTP `201`; a batch containing only retries returns `200`; and a batch with one or more failed items returns `207`. Results correspond to request items by `index` and `external_entry`.

```json
{
  "success": false,
  "message": "Document requests processed with one or more failed items.",
  "summary": {
    "total": 2,
    "created": 1,
    "idempotent": 0,
    "failed": 1
  },
  "data": [
    {
      "index": 0,
      "external_entry": 75,
      "success": true,
      "status": 201,
      "idempotent": false,
      "data": {
        "id": 125,
        "external_entry": 75,
        "document_code": "UHS75",
        "uhs_code": "2026-0042",
        "status": "submit"
      }
    },
    {
      "index": 1,
      "external_entry": 76,
      "success": false,
      "status": 422,
      "message": "Document type is not available for student requests."
    }
  ]
}
```

## 4. List AMS Student Requests Stored in DTS

AMS Student can call this endpoint to verify requests that were already submitted into DTS.

```http
GET https://dts.datacolabx.com/api/external/student/document-requests
```

Example:

```bash
curl -X GET "https://dts.datacolabx.com/api/external/student/document-requests?per_page=10" \
  -H "Accept: application/json" \
  -H "X-External-Api-Key: <shared-api-key>"
```

Optional query parameters:

| Parameter | Example | Description |
| --- | --- | --- |
| `document_code` | `UHS75` | Filter by AMS Student visible request code. |
| `external_entry` | `75` | Filter by AMS Student database row ID. |
| `status` | `pending` | Filter by raw DTS request status. |
| `per_page` | `10` | Pagination size, maximum `100`. |

Success response:

```json
{
  "success": true,
  "data": [
    {
      "id": 125,
      "external_entry": 75,
      "document_code": "UHS75",
      "uhs_code": "2026-0042",
      "document_name": "Academic Transcript Request",
      "document_type": "Academic Transcript",
      "status": "pending",
      "dts_status": "pending",
      "workflow_state": "organization_review",
      "public_tracking_token": "c0f1...",
      "created_at": "2026-07-10T08:12:30.000000Z",
      "updated_at": "2026-07-10T08:12:30.000000Z"
    }
  ],
  "page": 1,
  "per_page": 10,
  "total": 1
}
```

## 5. DTS Status Sync Back to AMS Student

When the request status changes in DTS, DTS calls the AMS Student update-status endpoint.

AMS Student endpoint:

```http
PATCH https://student.datacolabx.com/api/document-requests/{entry}
```

`{entry}` is the AMS Student database row ID sent to DTS as `external_entry`.

Example:

```http
PATCH https://student.datacolabx.com/api/document-requests/75
Accept: application/json
Content-Type: application/json
```

Body sent by DTS:

```json
{
  "status": "progressing"
}
```

Status mapping:

| DTS workflow result | AMS Student status |
| --- | --- |
| Submitted into DTS, but no workflow action has happened yet | `pending` |
| Workflow has started: forwarded, sent back, approved internally, or under review | `progressing` |
| Completed in DTS | `approved` |
| Rejected | `rejected` |

## Error Responses

Unauthorized API key:

```json
{
  "success": false,
  "message": "Unauthorized external API key."
}
```

Unavailable document type:

```json
{
  "success": false,
  "message": "Document type is not available for student requests."
}
```

Workflow configuration issue:

```json
{
  "success": false,
  "message": "No active workflow is configured for the selected document type. Note: please contact admin."
}
```

## Important Notes

- Always send `external_entry`.
- `external_entry` must be the AMS Student request row ID, for example `75`.
- `document_code` can be the visible AMS Student request code, for example `UHS75`.
- DTS uses `external_entry`, not `document_code`, when syncing status back to AMS Student.
- DTS keeps its own internal `id`; it will not reuse the AMS Student ID as the DTS ID.
