개발자 가이드

본 문서는 INNORIX Public API v2.0.0 기준입니다. 모든 응답은 statusCode · message · data · isCached 형식이며, status_code(snake_case)는 하위호환을 위해 남아 있지만 statusCode 사용을 권장합니다.

API 인증

애플리케이션이 INNORIX와 통신하려면 먼저 인증해야 합니다.

로그인과 토큰

설명

계정으로 로그인해 액세스 토큰(JWT) 을 발급받고, 이후 모든 요청에 Authorization: Bearerx-workspace-id 헤더를 함께 보냅니다. 토큰이 만료되면 POST /api/auth/token/refresh(헤더 X-Refresh-Token, 본문 없음)로 갱신합니다. 명령 자동화용 장기 키가 필요하면 POST /api/auth/api-keys(본문 없음)로 발급해 x-api-key 헤더로 사용합니다. 사용자당 활성 API 키는 1개이며, 재호출 시 동일한 키가 반환됩니다.

사용 API

목적MethodEndpoint
로그인POST/api/auth/login
토큰 갱신POST/api/auth/token/refresh
API 키 발급POST/api/auth/api-keys
현재 사용자 조회GET/api/auth/me

Request

POST /api/auth/login

json
{
  "email": "<YOUR_EMAIL>",
  "password": "<YOUR_PASSWORD>"
}

Response

json
{
  "statusCode": 200,
  "message": "success",
  "data": {
    "user": {
      "email": "user@example.com",
      "userName": "User Name",
      "userId": "usr_abc123",
      "accessToken": "<ACCESS_TOKEN>",
      "refreshToken": "<REFRESH_TOKEN>"
    }
  },
  "isCached": false
}

처리 순서

  1. POST /api/auth/login으로 로그인 → data.user.accessToken 수신
  2. 이후 요청에 Authorization: Bearer <ACCESS_TOKEN>x-workspace-id 헤더 부착
  3. 토큰 만료 시 POST /api/auth/token/refresh(헤더 X-Refresh-Token)로 갱신 → data.accessToken · data.refreshToken · data.expiresIn 수신

구현 예제

BASE_URL="https://app.innorix.com"
WORKSPACE_ID="<WORKSPACE_ID>"

ACCESS_TOKEN=$(curl -s -X POST "$BASE_URL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"<YOUR_EMAIL>","password":"<YOUR_PASSWORD>"}' \
  | jq -r '.data.user.accessToken')

AUTH=(-H "Authorization: Bearer $ACCESS_TOKEN" -H "x-workspace-id: $WORKSPACE_ID")

시스템 연결

파일 전송은 연결된 장비(device) 사이에서 일어납니다.

디바이스 확인과 파일 탐색

설명

장비 목록을 조회하거나, 이름·IP·MAC을 GET /api/devices/resolve로 정확한 deviceId로 변환합니다. 즉시 전송(POST /api/transfers/manual)은 소스·대상에 deviceId뿐 아니라 이름·IP도 그대로 받고 평문 경로를 전송하므로, 대부분의 경우 별도 탐색 없이 바로 전송할 수 있습니다. 필요할 때만 POST /api/devices/{deviceId}/files/search로 경로를 배치 탐색합니다. 이 탐색은 커서 기반 페이지네이션으로, 응답의 nextCursorGET /api/devices/{deviceId}/files/search?cursor=에 넘겨 hasMorefalse가 될 때까지 반복합니다. (에이전트 설치·등록은 완료된 상태를 전제로 하며, 설치된 에이전트가 서버에 연결되면 장비 목록에 나타납니다.)

사용 API

목적MethodEndpoint
디바이스 목록GET/api/devices
디바이스 확인(이름·IP·MAC → ID)GET/api/devices/resolve
연결 상태 조회GET/api/devices/{deviceId}/connectivity
파일 검색 시작POST/api/devices/{deviceId}/files/search
파일 검색 다음 배치GET/api/devices/{deviceId}/files/search?cursor=

Request

POST /api/devices/{deviceId}/files/search

json
{
  "path": "C:/data/export",
  "pageSize": 500
}

Response

GET /api/devices/resolve?name=seoul-node-01

json
{
  "statusCode": 200,
  "message": "success",
  "data": {
    "matchCount": 1,
    "devices": [
      { "deviceId": "6901ae48ca578216fd739f78", "name": "seoul-node-01", "os": "linux", "status": 1 }
    ]
  }
}

GET /api/devices/{deviceId}/connectivity

json
{
  "statusCode": 200,
  "message": "success",
  "data": { "deviceId": "6901ae48ca578216fd739f78", "state": 1, "isConnected": true }
}

POST /api/devices/{deviceId}/files/search

json
{
  "statusCode": 200,
  "message": "OK",
  "data": {
    "searchId": "srch_9f2a3c",
    "items": [
      { "name": "report.pdf", "path": "C:/data/export/report.pdf", "type": "file", "size": 20480 }
    ],
    "count": 1,
    "hasMore": false,
    "nextCursor": null
  }
}

처리 순서

  1. GET /api/devices 또는 GET /api/devices/resolve로 소스·대상 deviceId 확인 (즉시 전송에는 이름·IP도 그대로 사용 가능)
  2. GET /api/devices/{deviceId}/connectivity로 두 장비 isConnected 여부 확인
  3. (선택) POST /api/devices/{deviceId}/files/search({path, pageSize})로 첫 배치 조회 → nextCursor·hasMore 확인, GET ...?cursor=로 반복. 자동화의 sourceItem{deviceId}_ino_{base64(path)} 토큰이 필요합니다(아래 일정 자동화 참고).

구현 예제

# --- List devices ---
curl -s "$BASE_URL/api/devices?page=1&size=20" "${AUTH[@]}"

# --- Resolve a name / IP into an exact deviceId ---
curl -s "$BASE_URL/api/devices/resolve?name=seoul-node-01" "${AUTH[@]}"

# --- Check connectivity ---
curl -s "$BASE_URL/api/devices/<DEVICE_ID>/connectivity" "${AUTH[@]}"

# --- Browse a device path (start) ---
curl -s -X POST "$BASE_URL/api/devices/<DEVICE_ID>/files/search" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{"path":"C:/data/export","pageSize":500}'

# --- Browse a device path (next batch) ---
curl -s "$BASE_URL/api/devices/<DEVICE_ID>/files/search?cursor=<NEXT_CURSOR>" "${AUTH[@]}"

파일 · 폴더 전송

소스 장비의 파일을 대상 장비로 보내고, 진행 중 제어·결과 확인을 수행합니다.

즉시 전송과 제어

설명

소스·대상 장비(sourceDevice/targetDevicedeviceId·이름·IP 모두 허용)와 평문 경로로 전송을 생성하면 monitorId가 반환됩니다(응답 data.monitorId). 폴더 루트는 sourcePaths로 넘기면 에이전트가 walk하며, 알려진 파일 목록은 sourceItem{ path, isDir: false, fileSize }로 지정하면 더 빠릅니다. 상태는 GET /api/transfers/{monitorId}로 폴링(정수 status·percent·isTerminal)하고, pause·resume·cancel202로 비동기 접수됩니다. 실패 파일은 retry로 재시도하고, 파일 단위 결과는 GET /api/transfers/{monitorId}/files?idType=monitor로 조회합니다.

사용 API

목적MethodEndpoint
전송 생성POST/api/transfers/manual
상태 조회GET/api/transfers/{monitorId}
전송 제어POST/api/transfers/{monitorId}/pause · resume · cancel
실패 재시도POST/api/transfers/{monitorId}/retry
전송 파일 조회GET/api/transfers/{monitorId}/files

Request

POST /api/transfers/manual

json
{
  "sourceDevice": "seoul-node-01",
  "targetDevice": "hanoi-node-02",
  "targetPath": "/data/incoming",
  "sourcePaths": ["/data/export"],
  "sendAllFolder": false,
  "transferOptions": { "target-action": "numbering" }
}

알려진 파일 목록을 정밀 지정하려면 sourcePaths 대신 sourceItem을 사용합니다: "sourceItem": [{ "path": "/data/export/report.pdf", "isDir": false, "fileSize": 20480 }]. target-actionnumbering(자동 이름변경) · overwrite(덮어쓰기) · nosend(동일 파일 시 미전송) 중 하나입니다.

Response

json
{
  "statusCode": 201,
  "message": "Created",
  "data": {
    "monitorId": "D5273-6820-6280-0345",
    "transferId": "tr_5566",
    "status": 1,
    "statusName": "StartTransfer",
    "isTerminal": false
  }
}

전송 상태 코드: 0 대기 · 1 시작 · 2 완료 · 3 일시중지 · 4 오류 · 5 취소 · 6 전송중 · 9 부분완료 · 99 실패. 종료(완료 판정) 상태 = {2, 4, 5, 9, 99}.

처리 순서

  1. POST /api/transfers/manual 호출 → data.monitorId 수신
  2. GET /api/transfers/{monitorId}status·percent·isTerminal 폴링
  3. 필요 시 POST /api/transfers/{monitorId}/pause · resume · cancel로 제어(202 비동기 접수), 실패는 .../retry({ filesRetry })로 재시도

구현 예제

# --- Create a transfer ---
curl -s -X POST "$BASE_URL/api/transfers/manual" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceDevice": "seoul-node-01",
    "targetDevice": "hanoi-node-02",
    "targetPath": "/data/incoming",
    "sourcePaths": ["/data/export"],
    "sendAllFolder": false,
    "transferOptions": { "target-action": "numbering" }
  }'

# --- Poll transfer status ---
curl -s "$BASE_URL/api/transfers/<MONITOR_ID>" "${AUTH[@]}"

# --- Control a transfer (pause / resume / cancel) ---
curl -s -X POST "$BASE_URL/api/transfers/<MONITOR_ID>/pause"  "${AUTH[@]}"
curl -s -X POST "$BASE_URL/api/transfers/<MONITOR_ID>/resume" "${AUTH[@]}"
curl -s -X POST "$BASE_URL/api/transfers/<MONITOR_ID>/cancel" "${AUTH[@]}"

# --- Retry failed files ---
curl -s -X POST "$BASE_URL/api/transfers/<MONITOR_ID>/retry" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{ "filesRetry": [ { "filePath": "/data/export/file.txt", "isFolder": false } ] }'

일정 자동화

정해진 시간에 반복 실행되는 예약 전송을 구성합니다.

반복 자동화

설명

스케줄과 전송 상세(details)를 담아 자동화를 생성하면 automationId가 반환되며, 이 값으로 조회·일시정지·재개·수정·삭제합니다. 반복 스케줄은 transferTypenormal로 두고 schedules[].typeday·week·month 등으로 지정하며, 시각은 12시간제 hour("01""12"minute·ampm(am/pm)로 표현합니다. details[].sourceItem은 즉시 전송과 달리 {deviceId}_ino_{base64(path)} 토큰(hash 필드)이 필요하고, senderId/receiverIddeviceId입니다. 실행 이력·상태는 GET /api/automations/{automationId}/executions로 확인합니다.

사용 API

목적MethodEndpoint
자동화 생성POST/api/automations
자동화 조회GET/api/automations/{automationId}
실행 이력 조회GET/api/automations/{automationId}/executions
자동화 일시정지POST/api/automations/{automationId}/pause
자동화 수정PATCH/api/automations/{automationId}
자동화 삭제DELETE/api/automations/{automationId}

Request

POST /api/automations

json
{
  "name": "Daily Settlement Transfer",
  "transferType": "normal",
  "timezone": "Asia/Seoul",
  "schedules": [
    {
      "type": "day",
      "startDateType": "now",
      "hour": "02",
      "minute": "00",
      "ampm": "am",
      "startDate": "2026-01-01T00:00:00.000Z",
      "timezone": "Asia/Seoul"
    }
  ],
  "details": [
    {
      "senderId": "6901ae48ca578216fd739f78",
      "receiverId": "690037c22d309a7bc494bc53",
      "sourceItem": [
        { "hash": "6901ae48ca578216fd739f78_ino_L2RhdGEvcmVwb3J0LnBkZg==", "isDir": false }
      ],
      "targetPath": "/data/incoming",
      "step": 1,
      "transferOptions": { "target-action": "numbering" }
    }
  ]
}

hash 토큰은 <deviceId>_ino_<base64(path)> 형식입니다. 예: deviceId6901ae48ca578216fd739f78이고 경로가 /data/report.pdf이면, 경로를 base64로 인코딩(L2RhdGEvcmVwb3J0LnBkZg==)해 붙입니다. typeweek이면 dayInWeek(요일명 배열), month이면 dayInMonth(일자 배열)가 추가로 필요합니다.

Response

json
{
  "statusCode": 200,
  "message": "success",
  "data": { "automationId": "auto_301" }
}

처리 순서

  1. POST /api/automations 호출 → data.automationId 수신
  2. GET /api/automations/{automationId}/executions로 실행 이력·상태 확인
  3. POST /api/automations/{automationId}/pause({ "pause": true })로 일시정지/재개, PATCH({ isUpdateSchedule, schedules }DELETE로 수정·삭제

구현 예제

# --- Build the `<deviceId>_ino_<base64(path)>` token ---
DEVICE_ID="6901ae48ca578216fd739f78"
TOKEN="${DEVICE_ID}_ino_$(printf '%s' '/data/report.pdf' | base64)"

# --- Create an automation (every day at 02:00 AM) ---
curl -s -X POST "$BASE_URL/api/automations" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily Settlement Transfer",
    "transferType": "normal",
    "timezone": "Asia/Seoul",
    "schedules": [
      { "type": "day", "startDateType": "now", "hour": "02", "minute": "00", "ampm": "am",
        "startDate": "2026-01-01T00:00:00.000Z", "timezone": "Asia/Seoul" }
    ],
    "details": [
      {
        "senderId": "6901ae48ca578216fd739f78",
        "receiverId": "690037c22d309a7bc494bc53",
        "sourceItem": [ { "hash": "'"$TOKEN"'", "isDir": false } ],
        "targetPath": "/data/incoming",
        "step": 1,
        "transferOptions": { "target-action": "numbering" }
      }
    ]
  }'

# --- Read / list executions ---
curl -s "$BASE_URL/api/automations/<AUTOMATION_ID>" "${AUTH[@]}"
curl -s "$BASE_URL/api/automations/<AUTOMATION_ID>/executions" "${AUTH[@]}"

# --- Pause / resume ---
curl -s -X POST "$BASE_URL/api/automations/<AUTOMATION_ID>/pause" "${AUTH[@]}" \
  -H "Content-Type: application/json" -d '{"pause": true}'

# --- Update / delete ---
curl -s -X PATCH "$BASE_URL/api/automations/<AUTOMATION_ID>" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Daily Settlement Transfer", "isUpdateSchedule": true, "schedules": [] }'
curl -s -X DELETE "$BASE_URL/api/automations/<AUTOMATION_ID>" "${AUTH[@]}"