# Get a presigned scan upload URL

Operation ID: `diagnostics.getScanUploadUrl`

Return a presigned URL for uploading a photo/scan of a rapid test result, associated with an existing test_id. Call diagnostics.createRapidTest first to obtain a test_id — this endpoint 404s if test_id does not resolve to an existing test for the patient.

## Public method

`getScanUploadUrl`

Signature: `diagnostics.getScanUploadUrl(patientId, request)`

Return type: `Promise<ScanUploadUrlResponse>`

## Authentication

Classification: **AUTHENTICATED**

Schemes: `bearerAuth`

## Prerequisites

None documented.

## HTTP

`POST /patients/{patient_id}/diagnostics/scan-upload-url`

## Path parameters

| Name | Type | Required | Format | Allowed values | Default | Nullable | Description |
|---|---|---:|---|---|---|---:|---|
| `patient_id` | `string` | Yes |  |  |  | No |  |

## Query parameters

None.

## Body parameters

| Name | Type | Required | Format | Allowed values | Default | Nullable | Description |
|---|---|---:|---|---|---|---:|---|
| `body` | [`GetScanUploadUrlRequest`](../models/GetScanUploadUrlRequest.md) | Yes |  |  |  | No |  |

Request model: [`GetScanUploadUrlRequest`](../models/GetScanUploadUrlRequest.md)

## Request example

```json
{
  "content_type": "image/jpeg",
  "encounter_id": "string",
  "filename": "scan.jpg",
  "gtin": "string",
  "test_id": "00000000-0000-0000-0000-000000000000"
}
```

## Success responses

| Status | Shape | Content type | Description |
|---|---|---|---|
| `200` | [`ScanUploadResponse`](../models/ScanUploadResponse.md) | application/json | Presigned upload URL for a test scan image |

## Success response examples

### 200

```json
{
  "expires_in": 3600,
  "storage_key": "diagnostics/test-scan.jpg",
  "test_id": "00000000-0000-4000-8000-000000000001",
  "upload_url": "https://example.com/uploads/test-scan.jpg"
}
```

## Common errors

| Status | Shape | Content type | Description |
|---|---|---|---|
| `400` | [`diagnostics.ErrorResponse`](../models/diagnostics.ErrorResponse.md) | application/json | test_id was missing or not a valid UUID |
| `401` | [`diagnostics.ErrorResponse`](../models/diagnostics.ErrorResponse.md) | application/json | Authorization required — missing or invalid Bearer JWT |
| `403` | [`diagnostics.ErrorResponse`](../models/diagnostics.ErrorResponse.md) | application/json | A PATIENT-pool caller attempted to access another patient's data |
| `404` | [`diagnostics.ErrorResponse`](../models/diagnostics.ErrorResponse.md) | application/json | The PATIENT-pool caller's own FHIR Patient record could not be resolved |
| `500` | [`diagnostics.ErrorResponse`](../models/diagnostics.ErrorResponse.md) | application/json | Internal server error |

## Error examples

### 400 — test_id is missing or not a valid UUID

```json
{
  "error": "Invalid or missing test_id (UUID required)"
}
```

### 401 — Missing or invalid access token

```json
{
  "error": "Authorization required"
}
```

### 403 — The caller's own FHIR patient id does not match patient_id

```json
{
  "error": "Cannot access another patient's data"
}
```

### 404 — The caller's own patient record was not found

```json
{
  "error": "Patient not found"
}
```

### 500 — Unexpected service failure (sanitized example)

```json
{
  "error": "Internal server error"
}
```

## NodeJS / TypeScript implementation

```ts
import { HCSDK } from "@healthcloudai/hc-sdk";
```

```ts
const patientId = "<PATIENT_ID>";

const request = {
  "content_type": "image/jpeg",
  "encounter_id": "string",
  "filename": "scan.jpg",
  "gtin": "string",
  "test_id": "00000000-0000-0000-0000-000000000000"
};

const result = await diagnostics.getScanUploadUrl(patientId, request);
```

## cURL

```bash
curl -X POST \
  -H 'Authorization: Bearer <ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"content_type":"image/jpeg","encounter_id":"string","filename":"scan.jpg","gtin":"string","test_id":"00000000-0000-0000-0000-000000000000"}' \
  'https://dev-api-diagnostics.health.cloud/patients/%3CPATIENT_ID%3E/diagnostics/scan-upload-url'
```

## Notes

None.

## Prepared Test Console scenario

No canonical scenario is currently associated.

## Real response

No approved real integration response is currently published. Unapproved candidates are never rendered as examples.
