API 경로별 명세
아래는 내부 작업 제어 API입니다. 기준 경로는 /api/bridge/v1이며, 병원용 공개 업로드 API가 아닙니다. 인증·헤더·전체 스키마는 OpenAPI JSON과 아래 설명을 함께 확인하세요.
GET /connectors연결 설정 목록 조회
로컬 합성 자료용 연결 설정입니다. 운영 병원 어댑터는 제공하지 않습니다.
| HTTP | 결과 |
|---|
| 200 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| items | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"items": [
{
"id": "hospital-a",
"version": "1",
"destination_org_id": "hospital-a",
"adapter": "synthetic",
"channels": [
"fhir"
],
"verification_level": "synthetic",
"enabled": false,
"max_concurrency": 1,
"live_supported": false
}
]
}
POST /connectors연결 설정 등록
로컬 합성 자료용 연결 설정입니다. 운영 병원 어댑터는 제공하지 않습니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| version | string | 필수 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| destination_org_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| adapter | string | 선택 | 허용값: synthetic, sandbox · 기본값: "synthetic" |
|---|
| channels | array | 필수 | 최소 항목 수: 1 · 최대 항목 수: 3 · 항목 허용값: fhir, dicom, omop |
|---|
| verification_level | string | 선택 | 허용값: synthetic, protocol_tested, institution_verified · 기본값: "synthetic" |
|---|
| enabled | boolean | 선택 | 기본값: false |
|---|
| max_concurrency | integer | 선택 | 기본값: 1 · 최솟값: 1 · 최댓값: 20 |
|---|
{
"id": "hospital-a",
"version": "1",
"destination_org_id": "hospital-a",
"adapter": "synthetic",
"channels": [
"fhir"
],
"verification_level": "synthetic",
"enabled": false,
"max_concurrency": 1
}
| HTTP | 결과 |
|---|
| 201 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 201 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| version | string | 필수 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| destination_org_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| adapter | string | 필수 | 허용값: synthetic, sandbox · 기본값: "synthetic" |
|---|
| channels | array | 필수 | 최소 항목 수: 1 · 최대 항목 수: 3 · 항목 허용값: fhir, dicom, omop |
|---|
| verification_level | string | 필수 | 허용값: synthetic, protocol_tested, institution_verified · 기본값: "synthetic" |
|---|
| enabled | boolean | 필수 | 기본값: false |
|---|
| max_concurrency | integer | 필수 | 기본값: 1 · 최솟값: 1 · 최댓값: 20 |
|---|
| live_supported | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "hospital-a",
"version": "1",
"destination_org_id": "hospital-a",
"adapter": "synthetic",
"channels": [
"fhir"
],
"verification_level": "synthetic",
"enabled": false,
"max_concurrency": 1,
"live_supported": false
}
POST /connectors/{connector_id}/{version}/stop연결 설정 중지
로컬 합성 자료용 연결 설정입니다. 운영 병원 어댑터는 제공하지 않습니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| connector_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| version | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| HTTP | 결과 |
|---|
| 200 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| version | string | 필수 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| destination_org_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| adapter | string | 필수 | 허용값: synthetic, sandbox · 기본값: "synthetic" |
|---|
| channels | array | 필수 | 최소 항목 수: 1 · 최대 항목 수: 3 · 항목 허용값: fhir, dicom, omop |
|---|
| verification_level | string | 필수 | 허용값: synthetic, protocol_tested, institution_verified · 기본값: "synthetic" |
|---|
| enabled | boolean | 필수 | 기본값: false |
|---|
| max_concurrency | integer | 필수 | 기본값: 1 · 최솟값: 1 · 최댓값: 20 |
|---|
| live_supported | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "hospital-a",
"version": "1",
"destination_org_id": "hospital-a",
"adapter": "synthetic",
"channels": [
"fhir"
],
"verification_level": "synthetic",
"enabled": false,
"max_concurrency": 1,
"live_supported": false
}
POST /connectors/{connector_id}/{version}/enable시험 연결 설정 활성화
로컬 합성 자료용 연결 설정입니다. 운영 병원 어댑터는 제공하지 않습니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| connector_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| version | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| HTTP | 결과 |
|---|
| 200 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| version | string | 필수 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| destination_org_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| adapter | string | 필수 | 허용값: synthetic, sandbox · 기본값: "synthetic" |
|---|
| channels | array | 필수 | 최소 항목 수: 1 · 최대 항목 수: 3 · 항목 허용값: fhir, dicom, omop |
|---|
| verification_level | string | 필수 | 허용값: synthetic, protocol_tested, institution_verified · 기본값: "synthetic" |
|---|
| enabled | boolean | 필수 | 기본값: false |
|---|
| max_concurrency | integer | 필수 | 기본값: 1 · 최솟값: 1 · 최댓값: 20 |
|---|
| live_supported | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "hospital-a",
"version": "1",
"destination_org_id": "hospital-a",
"adapter": "synthetic",
"channels": [
"fhir"
],
"verification_level": "synthetic",
"enabled": false,
"max_concurrency": 1,
"live_supported": false
}
POST /deliveries전송 작업 생성
실행자 범위의 작업을 생성하거나 기존 결과를 반환합니다. 같은 키의 재호출은 권한을 갱신하지 않습니다. 다른 본문은 422 idempotency-conflict, 다른 키의 중복 업무는 409입니다. 송수신 시험은 등록된 local/test 설정에서만 허용하며 운영 병원 송신은 비활성입니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| Idempotency-Key | 헤더 | string | 필수 | 작업 생성에 필수입니다. 실행자·조직·본문에 연결해 작업과 함께 보관합니다. 완료 참조 정리 후에도 업무 중복 방지 해시를 유지하며 24시간 뒤 재사용을 보장하지 않습니다. · 최소 길이: 1 · 최대 길이: 128 |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| grant_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| connector_id | string | 필수 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| connector_version | string | 필수 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| channels | array | 필수 | 최소 항목 수: 1 · 최대 항목 수: 3 · 항목 허용값: fhir, dicom, omop |
|---|
| dry_run | boolean | 선택 | 기본값: true |
|---|
| mapping_ref | string | 선택 | 기본값: "unmapped" · 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| mapping_version | string | 선택 | 기본값: "unmapped" · 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
{
"grant_id": "synthetic-grant",
"connector_id": "hospital-a",
"connector_version": "1",
"channels": [
"fhir"
],
"dry_run": true
}
| HTTP | 결과 |
|---|
| 200 | 같은 실행자·요청 키·본문의 재호출입니다. 기존 작업 메타데이터만 반환하고 전송 권한을 갱신하거나 연장하지 않습니다. |
|---|
| 202 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 413 | 승인 묶음이 크기 상한을 초과했습니다. |
|---|
| 422 | 같은 Idempotency-Key를 다른 본문에 사용했습니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "queued",
"dry_run": true,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "hospital-a",
"connector_id": "hospital-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:00:00Z",
"channels": [
{
"channel": "fhir",
"state": "queued",
"items": []
}
]
}
HTTP 202 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| Location | 전송 작업 상태를 조회하는 경로입니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "queued",
"dry_run": true,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "hospital-a",
"connector_id": "hospital-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:00:00Z",
"channels": [
{
"channel": "fhir",
"state": "queued",
"items": []
}
]
}
GET /deliveries/{delivery_id}전송 작업 조회
전송허가에 연결된 작업 API입니다. 운영 병원 송신은 비활성입니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| delivery_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| HTTP | 결과 |
|---|
| 200 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "queued",
"dry_run": true,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "hospital-a",
"connector_id": "hospital-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:00:00Z",
"channels": [
{
"channel": "fhir",
"state": "queued",
"items": []
}
]
}
POST /deliveries/{delivery_id}/cancel미전송 작업 취소
전송허가에 연결된 작업 API입니다. 운영 병원 송신은 비활성입니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| delivery_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| HTTP | 결과 |
|---|
| 200 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "queued",
"dry_run": true,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "hospital-a",
"connector_id": "hospital-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:00:00Z",
"channels": [
{
"channel": "fhir",
"state": "queued",
"items": []
}
]
}
POST /deliveries/{delivery_id}/retry실패 항목 재시도
전송허가에 연결된 작업 API입니다. 운영 병원 송신은 비활성입니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| delivery_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| grant_id | string | 선택 | 형식 규칙: ^[A-Za-z0-9_-]{1,64}$ |
|---|
| connector_version | string | 선택 | 형식 규칙: ^[A-Za-z0-9_.-]{1,32}$ |
|---|
| HTTP | 결과 |
|---|
| 202 | 작업 메타데이터만 반환합니다. 임상 본문과 영수증 원문은 포함하지 않습니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 413 | 승인 묶음이 크기 상한을 초과했습니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 202 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "queued",
"dry_run": true,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "hospital-a",
"connector_id": "hospital-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:00:00Z",
"channels": [
{
"channel": "fhir",
"state": "queued",
"items": []
}
]
}
POST /deliveries/{delivery_id}/reconcile수신 불명 결과 재조회
등록된 local/test 시험 어댑터가 uncertain·awaiting_confirmation 작업을 조회·대조합니다. 확인되지 않은 항목은 uncertain으로 남깁니다. 허가·연결 설정을 재확인하고 자료를 재전송하지 않습니다. 운영 병원 조회는 비활성입니다.
| 이름 | 위치 | 형식 | 필수 | 설명 |
|---|
| delivery_id | 경로 | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| Idempotency-Key | 헤더 | string | 선택 | 선택적인 요청 키입니다. UI는 사용자 행동마다 새로운 UUID를 보냅니다. · 최소 길이: 1 · 최대 길이: 255 |
|---|
| HTTP | 결과 |
|---|
| 200 | 로컬 시험 수신 조회를 마쳤습니다. 내용을 확인하지 못하면 수신 불명 상태를 유지합니다. |
|---|
| 400 | 형식이 잘못되었거나 필수 값이 없습니다. |
|---|
| 401 | 인증 토큰이 없거나 만료 또는 유효하지 않습니다. |
|---|
| 403 | 허용되지 않은 역할·범위이거나 서비스 전용 경로에 대한 외부 호출입니다. |
|---|
| 404 | 대상이 없거나 호출자 권한 밖입니다. 대상의 존재 여부를 노출하지 않습니다. |
|---|
| 409 | 작업 상태·허가 연결·중복 업무가 충돌하거나 실송신이 비활성입니다. |
|---|
| 503 | 의존 서비스가 실패했거나 제한시간을 초과했습니다. |
|---|
HTTP 200 응답
| 헤더 | 설명 |
|---|
| Cache-Control | 환자 자료가 포함된 응답은 캐시하지 않습니다. |
|---|
| 필드 | 형식 | 필수 | 설명 |
|---|
| id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| state | string | 필수 | 허용값: queued, preparing, validated, sending, awaiting_confirmation, confirmed, partial, blocked, failed, uncertain, cancelled |
|---|
| dry_run | boolean | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| issue_code | 선택 유형 | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| source_revision | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| destination_org_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_id | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| connector_version | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| versions | object | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| created_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| updated_at | string | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
| channels | array | 필수 | 상세 제약은 OpenAPI JSON 참조 |
|---|
{
"id": "00000000-0000-4000-8000-000000000001",
"state": "confirmed",
"dry_run": false,
"issue_code": null,
"source_revision": "synthetic-source-revision",
"destination_org_id": "lab-a",
"connector_id": "lab-a",
"connector_version": "1",
"versions": {
"schema": "1.0",
"transform": "0.1.0",
"fhir": "4.0.1",
"omop": "5.4",
"terminology": "unconfigured",
"codec": "unconfigured"
},
"created_at": "2026-11-05T00:00:00Z",
"updated_at": "2026-11-05T00:01:00Z",
"channels": [
{
"channel": "fhir",
"state": "confirmed",
"items": [
{
"id": "00000000-0000-4000-8000-000000000002",
"state": "confirmed",
"artifact_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"artifact_version": "1",
"attempts": 1,
"receipt_code": "receiver-confirmed"
}
]
}
]
}
명세의 적용 범위
이 문서는 병원 IT팀이 호출 방향·데이터·인증·오류·시험 조건을 검토하는 기술 첨부다. api/bridge-control.openapi.yaml은 현재 구현된 Bridge 내부 작업 제어 API이며, 병원이 호출할 수 있는 환자/영상 업로드 API를 의미하지 않는다. api/common.yaml을 같은 폴더에 두고 연다. 파일의 localhost 서버 주소는 로컬 예시다. 기관 운영 주소와 자격증명은 아직 발급하지 않았다.
| 구분 | 호출 방향 | 현재 상태 |
|---|
| Bridge 작업 제어 API | ailix의 권한 있는 실행자 → Bridge | 구현됨. 외부 병원 서비스 계정·scope 제공 없음 |
|---|
| FHIR 수신 API | Bridge → 병원 FHIR 서버 또는 승인된 중계 서버 | 표준 R4 로컬 시험 완료. 병원 endpoint·인증·규격 확인 필요 |
|---|
| PACS 저장·조회 | Bridge → 병원 PACS 또는 영상 게이트웨이 | STOW/DIMSE·WADO 로컬 시험 완료. 병원 적합성 확인 필요 |
|---|
| 연구 적재 | 승인된 연구 자료 → 연구환경 | 별도 합성 로컬 적재 구현. 병원용 공개 REST API 없음 |
|---|
| 병원 자료 수신 API 및 결과 웹훅 | 병원 → ailix | 미구현. 기관 인증·수신 계약·중복·정정·감사 설계 후 별도 개발 |
|---|
현재 구현된 작업 제어 API
기준 경로는 /api/bridge/v1이다. 아래 경로·형식은 첨부 OpenAPI가 정본이다. 현재 사용자 인증은 ailix 사용자 JWT이며 작업 API는 staff/abroad 또는 doctor/abroad 역할을 검사한다. 작업은 같은 원 조직·실행자만 조회할 수 있다. 커넥터 관리는 서비스 관리자 권한이다. 병원 IT 서비스에 일반 사용자 JWT를 공유하는 방식으로 연계하지 않는다.
| 메서드와 경로 | 입력 및 결과 | 제한 |
|---|
GET /connectors | 등록된 연결 설정 목록 | 관리자용. 비밀·실제 접속 URL을 요청으로 받지 않음 |
|---|
POST /connectors | 기관·커넥터 ID/버전·채널·어댑터 등록 | 관리자용. 로컬 synthetic/sandbox, 운영 실송신 차단 |
|---|
POST /connectors/{id}/{version}/stop | 해당 버전의 새 작업 실행 중지 | 관리자용 |
|---|
POST /connectors/{id}/{version}/enable | 허용된 시험 설정 활성화 | 관리자용. dev/prod 시험 어댑터 활성화 거절 |
|---|
POST /deliveries | 전송허가 참조로 비동기 작업 생성 | Idempotency-Key 필수. 환자 본문·영상·자유 목적지 URL 입력 금지 |
|---|
GET /deliveries/{delivery_id} | 작업·채널·항목 상태 및 해시 조회 | 본인 작업만, 임상 본문·환자번호·영수증 원문 없음 |
|---|
POST /deliveries/{delivery_id}/cancel | 미전송 작업 취소 | 병원 기록의 삭제/철회를 뜻하지 않음 |
|---|
POST /deliveries/{delivery_id}/retry | 실패 항목의 재시도 예약 | 허가·원천 버전 재확인. 수신 불명 자동 재전송 거절 |
|---|
POST /deliveries/{delivery_id}/reconcile | 수신 불명 결과 재조회·대조 | 명시적 로컬 sandbox만. 이 호출은 재전송하지 않음 |
|---|
POST /deliveries는 Note가 발급한 최대 15분 허가를 요구한다. 허가 발급과 내부 자료 조회는 별도의 Note 권한 경로다. 병원이 임의로 grant_id를 만들거나 임상 JSON을 이 API에 넣을 수 없다.
요청 예시
아래 값은 합성 예시이며 유효한 토큰이나 전송허가가 아니다. 별도 제공된 로컬 시험 설정에만 적용한다. 운영에서 dry_run=false를 허용하는 예제로 해석하지 않는다.
POST /api/bridge/v1/deliveries
Authorization: Bearer <발급받은 ailix 사용자 토큰>
Content-Type: application/json
Idempotency-Key: synthetic-it-review-001
{
"grant_id": "synthetic-expired-grant",
"connector_id": "lab-it-demo",
"connector_version": "1",
"channels": ["fhir"],
"dry_run": true,
"mapping_ref": "synthetic-reviewed-map",
"mapping_version": "1"
}
신규 요청은 202 Accepted, 동일 실행자·조직·요청 키·본문의 재호출은 기존 작업과 함께 200 OK를 반환한다. 202는 작업 접수이며 병원 등록 완료가 아니다. Location에 작업 조회 경로를 주고 Cache-Control: no-store를 적용한다. 응답 필드는 examples/control-delivery-response.example.json을 참조한다.
상태와 오류
| 값 | 의미와 호출자 조치 |
|---|
validated | dry-run 변환 검증 완료. 병원에 보내지 않음 |
|---|
confirmed | 해당 시험 어댑터에서 저장 내용 대조 완료. 임상 화면·최종 의무기록 인수는 별도 |
|---|
partial | 일부 성공. 실패 항목만 복구 |
|---|
blocked | 허가·연결·원천·매핑 보완 필요 |
|---|
uncertain / awaiting_confirmation | 수신 여부 확정 불가. 조회·대조 후 판단 |
|---|
failed / cancelled | 실패 / 미전송 취소. 재시도 가능 여부는 원인·허가·현재 상태로 결정 |
|---|
오류는 application/problem+json이며 code, request_id와 허용된 기계 사유를 사용한다. 실제 필드·상태코드·예시는 OpenAPI/common 명세를 따른다. 원문·환자번호·비밀은 오류에 넣지 않는다.
| HTTP | 예시 코드 | 처리 |
|---|
| 400 | validation-error | 필드/타입 수정 |
|---|
| 401 / 403 | unauthorized / forbidden | 인증·허용 역할·조직 확인 |
|---|
| 404 | not-found | 참조·권한 확인. 다른 조직의 존재를 노출하지 않음 |
|---|
| 409 | consent-required, invalid-state-transition | 허가·상태·다른 키의 중복 업무 확인. 같은 요청 무조건 재전송 금지 |
|---|
| 413 | payload-too-large | 승인된 묶음 크기 조정 |
|---|
| 422 | idempotency-conflict | 같은 키에 다른 본문을 보냈는지 확인 |
|---|
| 503 | dependency-unavailable | 원천 서비스/의존성 복구 후 현재 작업 상태부터 확인 |
|---|
원천 패키지 기본 상한은 8MiB, 작업 항목 상한은 기본 1,000개다. 이는 임상 업로드 API의 SLA가 아니다. 기관 API의 호출량·rate limit·파일/요청 상한·타임아웃·재시도 간격·장애 응답 기준은 접속 방식과 함께 확정한다.
병원 FHIR 수신 인터페이스
로컬 어댑터가 쓰는 경로에서 {FHIR_BASE}는 병원이 제공하는 FHIR R4 기준 URL이다. endpoint 이름을 병원 제품에 임의로 적용하지 않는다. 서버가 지원하지 않는 동작은 별도 커넥터가 필요하다.
| 메서드와 경로 | 목적 | 요구하는 결과 |
|---|
GET {FHIR_BASE}/metadata | CapabilityStatement 확인 | FHIR 4.0.1, 필요한 리소스·transaction·read/update와 update-create 동작 확인 |
|---|
GET {FHIR_BASE}/Patient/{id} | 기존 환자 연결 확인 | identifier의 system+value 일치 |
|---|
GET {FHIR_BASE}/Encounter/{id} | 기존 진료 연결 확인 | subject의 Patient 연결과 진료 identifier 일치 |
|---|
POST {FHIR_BASE} | Bundle.type=transaction 전송 | transaction-response, 각 쓰기 결과 확인 |
|---|
GET {FHIR_BASE}/{resourceType}/{id} | 저장 내용 및 ETag 조회 | 임상 값·참조·원천 버전 대조 |
|---|
Content-Type/Accept는 application/fhir+json을 사용한다. 실제 OAuth scope, mTLS, 접속망, TLS·인증서 정책과 접근 가능한 리소스/필드는 병원이 정한다. 이 표는 인증 없이 운영해도 된다는 뜻이 아니다.
현재 송신 임상 리소스는 DocumentReference, Condition, Observation, MedicationRequest, Provenance다. Patient·Encounter는 검수된 수신측 참조를 사용한다. 첨부 예시는 요약·수치검사·Provenance이며 모든 진단/약물 사례를 포함하지 않는다. custom source-version 확장은 api/source-version.fhir.json을 제공한다. 기관의 확장 허용 정책을 확인한다.
최초 쓰기는 transaction entry의 request.ifNoneMatch="*", 정정은 이전 원천 버전과 수신 ETag를 확인한 request.ifMatch를 사용한다. 두 값은 Bundle 내부의 request 필드다. 서버가 해당 조건부 동작을 지원하는지 확인해야 한다. 환자·진료 리소스를 새로 만들지 않는다. 수신 리소스 ID는 수신기관별로 분리하고, 누락·충돌·이전 버전은 차단한다.
예제: examples/fhir-transaction.example.json, fhir-transaction-response.example.json, fhir-patient-registration.example.json, fhir-encounter-registration.example.json. 등록 예시는 시험 환자/진료 준비용이며 현재 임상 어댑터가 Patient/Encounter를 생성한다는 뜻이 아니다. 응답 예시는 설명용이며 실제 병원의 응답 기록이 아니다. FHIR 오류는 병원 서버의 OperationOutcome 규칙도 확인한다.
병원 PACS 저장 및 조회 인터페이스
| 인터페이스 | 요청 및 데이터 | 확인 방식 |
|---|
| STOW-RS | POST {DICOMWEB_BASE}/studies, multipart/related 안 application/dicom | HTTP/인스턴스 결과를 점검하고 WADO로 내용 대조 |
|---|
| DIMSE C-STORE | 병원 지정 host·port·Called/Calling AE, 합의한 SOP Class·Transfer Syntax | C-STORE status 뒤 독립 조회. HTTP API가 아님 |
|---|
| WADO-RS | GET {DICOMWEB_BASE}/studies/{study}/series/{series}/instances/{instance} | 픽셀, 환자 발급체계/번호, UID·촬영 메타데이터 대조 |
|---|
현재 STOW 구현은 응답의 HTTP 상태를 분류하고 WADO 내용 대조로 최종 판정한다. 기관 STOW 인스턴스별 경고·실패 Sequence의 상세 해석은 공급사 규격에 맞춘 보완과 시험이 필요하다. 현재 DIMSE 경로도 WADO 조회를 요구하므로 DIMSE-only PACS는 조회/영수증 어댑터를 별도로 구현해야 한다. QIDO 검색·C-FIND/C-MOVE, Modality Worklist, 새 검사번호 발급은 제공한 것으로 간주하지 않는다.
환자 PatientID와 IssuerOfPatientID, 검사번호와 Study/Series/Instance 관계를 검수한다. 기존 UID의 내용이 다르면 덮어쓰지 않는다. 임상 좌우·방향·촬영값을 추정해 채우지 않는다. 시험 수신 응답 상한은 기본 8MiB이며 대용량 분할·스트리밍·압축 전송을 검증한 것은 아니다. 예제 examples/synthetic-sc.dcm은 생성된 16×16 시험 영상이며 임상 판독용이 아니다.
연구 CDM 및 데이터 항목
현재 OMOP 자료는 person, visit_occurrence, condition_occurrence, measurement, drug_exposure, observation_period, cdm_source의 제한 5.4 출력이다. schemas/omop-output-columns.json은 출력 열 목록이며 값 제약 전체를 표현한 CDM 명세가 아니다. 공식 스키마·표준개념·기관 필수값·연구 목적은 별도로 확인한다. 합성 MappingRelease와 OMOP 예시는 실제 코드 매핑이나 연구 적재 승인이 아니다.
| 자료 항목 | 형식과 규칙 | 연결 및 검수 |
|---|
| 환자·기관 | 원 기관/환자 참조, 수신기관, 수신 환자 identifier system+value | 이름 기반 자동 매칭 금지, 발급체계와 값 함께 확인 |
|---|
| 진료·검사 | 진료 ID/시각, Encounter identifier, 영상 Accession·Study/Series/Instance UID | 기존 진료와 환자 subject 확인, 영상 검사 연결 검수 |
|---|
| 임상 사실 | 요약·확정/오류선언·진단 상태, 원래 코드·값·단위·사실 시각 | 의심·부정·가족력·처방/실제 투여를 혼동하지 않음 |
|---|
| 숫자·시각 | 원천 정밀도·UCUM 단위·시간대 포함 시각 | 시간대 없는 시각·단위/사실 누락을 임의 추정하지 않음 |
|---|
| 정정·출처 | 원천 ID/버전·이전 버전·검수자/원문 참조 | 정정본과 재호출 구분, 새 버전 덮어쓰기 차단 |
|---|
| 영상 | 형식·용량·SHA-256·원본/가림/파생 구분·악성검사/메타데이터 승인 | 원본 부재/미검사/허가 불일치 차단 |
|---|
| 연구 | 별도 목적·가명 정수 ID·명시 관찰기간·검수 개념/vocabulary 버전 | 임상 동의 재사용·약물 노출기간 추정·가짜 개념 ID 사용 금지 |
|---|
schemas/export-package.schema.json은 Note→Bridge 내부 묶음 계약이다. records[].payload는 범용 object로 표현되므로 세부 임상 타입은 schemas/clinical-record-payload.schema.json을 함께 본다. 이 묶음을 병원 업로드 API에 그대로 제출할 수 있다는 뜻은 아니다. schemas/identity-link.schema.json과 합성 연결 예시에는 승인 근거·버전이 포함된다. 현재 정적 식별자 레지스트리는 로컬 시험용이며 실제 환자번호 저장·열람 위치는 기관 정책 후 확정한다.
병원이 ailix를 호출하는 연동의 추가 명세
필요 업무가 병원→ailix 수신 또는 병원 시스템의 작업 조회라면 아래 항목을 별도 설계·구현한다. 현재 구현된 API처럼 URL을 만들어 제시하지 않는다.
기관 서비스 계정의 토큰 발급·만료·회전·scope와 기관별 권한, 네트워크/인증서 정책
환자·진료·검사 식별자 해소와 자료 본문/파일 계약, 원본·가림·연구 목적 구분
파일 악성검사·비동기 수신·멱등성·정정·철회·중복 충돌·감사/보관 계약
작업 상태 조회와 수신 확인, 결과 웹훅이 필요하면 서명·이벤트 ID·재전송·순서·중복 처리
시험/운영 기준 URL, 허용량·상한·타임아웃, 오류·장애·지원·변경/폐기 버전 정책
버전과 제공 절차
이 첨부의 OpenAPI는 API 0.1.0, 문서는 0.1이며 Suite 제품 버전과 별도다. 기관별 합의 후 profile·mapping·connector 버전과 변경 이력을 고정한다. 파괴적 변경의 사전 통지·호환기간·폐기일은 기관 계약에서 정하며 현재 SLA나 날짜를 확약하지 않는다. 실제 운영 IP·기준 URL·OAuth/인증서·토큰·연결 키는 승인된 별도 경로로 제공한다.