ccairn

API 參考 · /api/v1

278 個端點,依 resource 分組。每個標出 HTTP method、路徑、 所需權限與模組閘。回應外殼與錯誤碼見 總覽。按 ⌘K 搜尋。

/accrual-ledger

掛帳台帳

GET/api/v1/accrual-ledger
ledger.read

參數

period必填
string· 格式限定

出團月(格式 YYYY-MM,Asia/Taipei 時區)

回應欄位 · data

period
string
departureSummary
object[]
departureId
string
tripTitle
string
departureDate
string
pax
number
revenueTwd
number
realCostTwd
number
grossProfitTwd
number
costLines
object[]
id
string
tripTitle
string
departureDate
string
category
string
vendor
string | null
amountTwd
number
invoiceAmountTwd
number
isDeclarable
boolean
reviewStatus
string
payables
object[]
payableNumber
string
tripTitle
string
payeeName
string
amountTwd
number
status
string
receivables
object[]
orderNumber
string
tripTitle
string
receivableTwd
number
receivedTwd
number
outstandingTwd
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/accrual-ledger?period=<period>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "period": "…",
    "departureSummary": [
      {
        "departureId": "…",
        "tripTitle": "…",
        "departureDate": "…",
        "pax": 0,
        "revenueTwd": 0,
        "realCostTwd": 0,
        "grossProfitTwd": 0
      }
    ],
    "costLines": [
      {
        "id": "…",
        "tripTitle": "…",
        "departureDate": "…",
        "category": "…",
        "vendor": "…",
        "amountTwd": 0,
        "invoiceAmountTwd": 0,
        "isDeclarable": true,
        "reviewStatus": "…"
      }
    ],
    "payables": [
      {
        "payableNumber": "…",
        "tripTitle": "…",
        "payeeName": "…",
        "amountTwd": 0,
        "status": "…"
      }
    ],
    "receivables": [
      {
        "orderNumber": "…",
        "tripTitle": "…",
        "receivableTwd": 0,
        "receivedTwd": 0,
        "outstandingTwd": 0
      }
    ]
  }
}

掛帳台帳的「梯次彙總」

GET/api/v1/accrual-ledger/departure-summary
ledger.read

參數

period必填
string· 格式限定

出團月(格式 YYYY-MM,Asia/Taipei 時區)

回應欄位 · data

period
string
departureSummary
object[]
departureId
string
tripTitle
string
departureDate
string
pax
number
revenueTwd
number
realCostTwd
number
grossProfitTwd
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/accrual-ledger/departure-summary?period=<period>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "period": "…",
    "departureSummary": [
      {
        "departureId": "…",
        "tripTitle": "…",
        "departureDate": "…",
        "pax": 0,
        "revenueTwd": 0,
        "realCostTwd": 0,
        "grossProfitTwd": 0
      }
    ]
  }
}

/agencies

同業

GET/api/v1/agencies
agency.read

參數

status選填
enum
activearchived

同業狀態篩選(active 啟用中/archived 已封存;省略為全部)

owner選填
string

負責業務篩選(傳明確使用者 ID;none=只列尚未指派負責業務者;all 或省略=全部)

hasTaxId選填
enum
yesno

是否有統一編號篩選(yes 僅列有統編者/no 僅列無統編者)

回應欄位 · data[]

id
string
name
string
taxId
string | null
contactName
string | null
phone
string | null
email
string | null
address
string | null
paymentTerm
string | null
ownerUserId
string | null
ownerName
string | null
status
"active" | "archived"
note
string | null
orderCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/agencies \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…",
      "taxId": "…",
      "contactName": "…",
      "phone": "…",
      "email": "…",
      "address": "…",
      "paymentTerm": "…",
      "ownerUserId": "…",
      "ownerName": "…",
      "status": "active",
      "note": "…",
      "orderCount": 0,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/agencies
agency.manage

參數

name必填
string· max 200 · min 1

同業公司名稱(B2B 旅行社或個人團主名稱)

taxId選填
string

統一編號(選填)

contactName選填
string

主要聯絡人姓名(選填)

phone選填
string

聯絡電話(選填)

email選填
value

聯絡 Email(選填;留空字串視為未填)

address選填
string

公司地址(選填)

paymentTerm選填
string

付款條件/帳期約定(選填,如月結 30 天)

ownerUserId選填
string· max 128

指派的負責業務使用者 ID(選填)

status選填
enum

同業狀態(active 啟用中/archived 已封存;預設 active)

note選填
string

內部備註(選填)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/agencies \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

單一同業完整資料

GET/api/v1/agencies/{id}
agency.read

參數

id路徑
string· min 1

同業 ID

回應欄位 · data

id
string
name
string
taxId
string | null
contactName
string | null
phone
string | null
email
string | null
address
string | null
paymentTerm
string | null
ownerUserId
string | null
ownerName
string | null
status
"active" | "archived"
note
string | null
orderCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/agencies/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "name": "…",
    "taxId": "…",
    "contactName": "…",
    "phone": "…",
    "email": "…",
    "address": "…",
    "paymentTerm": "…",
    "ownerUserId": "…",
    "ownerName": "…",
    "status": "active",
    "note": "…",
    "orderCount": 0,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
PATCH/api/v1/agencies/{id}
agency.manage

參數

id路徑
string· min 1

要更新的同業 ID

name選填
string· max 200 · min 1

同業公司名稱(省略則不更動)

taxId選填
string

統一編號(省略則不更動)

contactName選填
string

主要聯絡人姓名(省略則不更動)

phone選填
string

聯絡電話(省略則不更動)

email選填
value

聯絡 Email(省略則不更動;空字串視為清空)

address選填
string

公司地址(省略則不更動)

paymentTerm選填
string

付款條件/帳期約定(省略則不更動)

ownerUserId選填
string· max 128

指派的負責業務使用者 ID(省略則不更動)

status選填
enum

同業狀態(active 啟用中/archived 已封存;省略則不更動)

note選填
string

內部備註(省略則不更動)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/agencies/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

上下架同業

POST/api/v1/agencies/{id}/status
agency.manage

參數

id路徑
string· min 1

同業 ID

status必填
enum

目標狀態(active 上架啟用/archived 下架封存)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/agencies/<id>/status \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "<status>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

負責業務指派候選清單

GET/api/v1/agencies/assignable-staff
agency.read

回應欄位 · data[]

userId
string
name
string
role
string
請求
curl -X GET https://your-tenant.example.com/api/v1/agencies/assignable-staff \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "userId": "…",
      "name": "…",
      "role": "…"
    }
  ]
}

同業名單匯出

GET/api/v1/agencies/export
agency.read

參數

status選填
enum
activearchived

同業狀態篩選(active 啟用中/archived 已封存;省略為全部)

owner選填
string

負責業務篩選(傳明確使用者 ID;none=只列尚未指派負責業務者;all 或省略=全部)

hasTaxId選填
enum
yesno

是否有統一編號篩選(yes 僅列有統編者/no 僅列無統編者)

回應欄位 · data

rows
object[]
id
string
name
string
taxId
string | null
contactName
string | null
phone
string | null
email
string | null
address
string | null
paymentTerm
string | null
ownerUserId
string | null
ownerName
string | null
status
"active" | "archived"
note
string | null
orderCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/agencies/export \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "name": "…",
        "taxId": "…",
        "contactName": "…",
        "phone": "…",
        "email": "…",
        "address": "…",
        "paymentTerm": "…",
        "ownerUserId": "…",
        "ownerName": "…",
        "status": "active",
        "note": "…",
        "orderCount": 0,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "updatedAt": "2026-06-30T08:00:00.000Z"
      }
    ]
  }
}

/audit

list/filter the append-only tenant audit trail

GET/api/v1/audit/log
audit.read

參數

action選填
string

動作代碼篩選,例如 order.update(比對稽核事件的動作)

actor選填
string

操作者篩選,比對執行該動作的使用者 ID

entity選填
string

目標實體篩選,比對被操作對象的類型或 ID

from選填
string

起始時間(ISO 8601),僅回傳此時間之後的事件

to選填
string

結束時間(ISO 8601),僅回傳此時間之前的事件

limit選填
integer· max 1000

回傳筆數上限,最多 1000 筆

回應欄位 · data[]

id
string
actorUserId
string | null
actorEmail
string | null
actorName
string | null
action
string
targetType
string
targetId
string
metadata
unknown
ipAddress
string | null
createdAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/audit/log \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "actorUserId": "…",
      "actorEmail": "…",
      "actorName": "…",
      "action": "…",
      "targetType": "…",
      "targetId": "…",
      "metadata": "…",
      "ipAddress": "…",
      "createdAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

audit KPI counts

GET/api/v1/audit/stats
audit.read

參數

actor選填
string

操作者使用者 ID,指定時將統計數據限縮至該操作者

回應欄位 · data

eventsThisMonth
number
eventsToday
number
writesThisMonth
number
distinctActorsThisMonth
number
請求
curl -X GET https://your-tenant.example.com/api/v1/audit/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "eventsThisMonth": 0,
    "eventsToday": 0,
    "writesThisMonth": 0,
    "distinctActorsThisMonth": 0
  }
}

/cost-templates

list reusable series-tour cost templates

GET/api/v1/cost-templates
cost_template.read

參數

status選填
enum
activearchived

依狀態篩選:active 啟用、archived 已封存

active選填
boolean

啟用時只回傳輕量的 { id, name } 綁定挑選清單(行程設定的成本範本下拉用)

回應欄位 · data[]

id
string
name
string
請求
curl -X GET https://your-tenant.example.com/api/v1/cost-templates \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…"
    }
  ]
}
POST/api/v1/cost-templates
cost_template.manage

參數

name必填
string· max 120 · min 1

成本範本名稱

description選填
string· max 500

成本範本說明

status選填
enum
activearchived

範本狀態:active 啟用、archived 已封存

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/cost-templates \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

full cost-template detail

GET/api/v1/cost-templates/{id}
cost_template.read

參數

id路徑
string· min 1

成本範本 ID

回應欄位 · data

lines
object[]
id
string
templateId
string
category
string
vendorName
string | null
description
string | null
unitPriceTwd
number
quantityMode
QuantityMode
quantityFixed
number | null
headcountComponents
HeadcountComponent[] | null
groupDivisor
number | null
isDeclarable
boolean
sortOrder
number
id
string
name
string
description
string | null
status
"active" | "archived"
lineCount
number
boundTripCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/cost-templates/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "lines": [
      {
        "id": "…",
        "templateId": "…",
        "category": "…",
        "vendorName": "…",
        "description": "…",
        "unitPriceTwd": 0,
        "quantityMode": "…",
        "quantityFixed": 0,
        "headcountComponents": null,
        "groupDivisor": 0,
        "isDeclarable": true,
        "sortOrder": 0
      }
    ],
    "id": "…",
    "name": "…",
    "description": "…",
    "status": "active",
    "lineCount": 0,
    "boundTripCount": 0,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
PATCH/api/v1/cost-templates/{id}
cost_template.manage

參數

name必填
string· max 120 · min 1

成本範本名稱

description選填
string· max 500

成本範本說明

status選填
enum
activearchived

範本狀態:active 啟用、archived 已封存

id路徑
string· min 1

成本範本 ID

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/cost-templates/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

add a cost line to a template.

POST/api/v1/cost-templates/{id}/lines
cost_template.manage

參數

id路徑
string· min 1

成本範本 ID

line必填
object

成本明細列:含 category 科目、vendorName 廠商、unitPriceTwd 單價、quantityMode 計量方式(fixed 固定/headcount 人數)與對應數量/人數組成、isDeclarable 是否可報帳等欄位

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/cost-templates/<id>/lines \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "line": "<line>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

update or delete a

PATCH/api/v1/cost-templates/lines/{lineId}
cost_template.manage

參數

lineId路徑
string· min 1

成本範本明細行 ID

line必填
object

成本明細列更新內容:含 category 科目、vendorName 廠商、unitPriceTwd 單價、quantityMode 計量方式(fixed 固定/headcount 人數)與對應數量/人數組成、isDeclarable 是否可報帳等欄位

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/cost-templates/lines/<lineId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "line": "<line>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/cost-templates/lines/{lineId}
cost_template.manage

參數

lineId路徑
string· min 1

成本範本明細行 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/cost-templates/lines/<lineId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/departures

設定梯次分配模式

PATCH/api/v1/departures/{depId}/allocation-mode
lottery.manage模組:lottery

參數

depId路徑
string· min 1

梯次 ID

mode必填
enum
fcfslottery

分配模式:fcfs(先到先得)或 lottery(抽籤)

回應欄位 · data

ok
boolean
departureId
string
mode
"fcfs" | "lottery"
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/allocation-mode \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "fcfs"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "departureId": "…",
    "mode": "fcfs"
  }
}

登錄梯次成本

POST/api/v1/departures/{depId}/costs
departure_cost.create

參數

depId路徑
string· min 1

梯次 ID

category必填
string· min 1

成本科目類別,決定歸入哪個分類帳

vendorName選填
string

供應商/受款對象名稱

description選填
string

成本說明備註

amountTwd必填
integer

成本金額(台幣,整數)

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/costs \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "<category>",
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}
PATCH/api/v1/departures/{depId}/costs/{costId}
departure_cost.manage

參數

costId路徑
string· min 1

成本列 ID

category必填
string· min 1

成本科目類別,決定歸入哪個分類帳

vendorName選填
string

供應商/受款對象名稱

description選填
string

成本說明備註

amountTwd必填
integer

成本金額(台幣,整數)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/{depId}/costs/<costId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "<category>",
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/departures/{depId}/costs/{costId}
departure_cost.manage

參數

costId路徑
string· min 1

成本列 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/{depId}/costs/<costId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

該梯次財務摘要

GET/api/v1/departures/{depId}/finance-summary
departure.update

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data

header
object
id
string
tripTitle
string
tripSlug
string
departureDate
string
returnDate
string
finance
object
receivableTwd
number
collectedTwd
number
cashReturnedTwd
number
outstandingTwd
number
costTwd
number
costBilledTwd
number
costUnbilledTwd
number
anomalyOrderCount
number
cost
object
totalTwd
number
billedTwd
number
unbilledTwd
number
declarableTwd
number
nonDeclarableTwd
number
count
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/finance-summary \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "header": {
      "id": "…",
      "tripTitle": "…",
      "tripSlug": "…",
      "departureDate": "…",
      "returnDate": "…"
    },
    "finance": {
      "receivableTwd": 0,
      "collectedTwd": 0,
      "cashReturnedTwd": 0,
      "outstandingTwd": 0,
      "costTwd": 0,
      "costBilledTwd": 0,
      "costUnbilledTwd": 0,
      "anomalyOrderCount": 0
    },
    "cost": {
      "totalTwd": 0,
      "billedTwd": 0,
      "unbilledTwd": 0,
      "declarableTwd": 0,
      "nonDeclarableTwd": 0,
      "count": 0
    }
  }
}

該梯次抽籤訂單清單

GET/api/v1/departures/{depId}/lottery-orders
order.read

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data[]

orderId
string
orderNumber
string
customerName
string
partySize
number
lotteryState
"applied" | "won" | "lost"
backupChoiceCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/lottery-orders \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "orderId": "…",
      "orderNumber": "…",
      "customerName": "…",
      "partySize": 0,
      "lotteryState": "applied",
      "backupChoiceCount": 0
    }
  ]
}

該梯次旅客名單

GET/api/v1/departures/{depId}/manifest
order.read

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data[]

orderId
string
orderNumber
string
travelerName
string
phone
string
email
string
isPrimary
boolean
orderStatus
string
amount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/manifest \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "orderId": "…",
      "orderNumber": "…",
      "travelerName": "…",
      "phone": "…",
      "email": "…",
      "isPrimary": true,
      "orderStatus": "…",
      "amount": 0
    }
  ]
}

成本轉請款:以選定的未轉成本列建立一張

POST/api/v1/departures/{depId}/payables
payable.create

參數

depId路徑
string· min 1

梯次 ID

costIds必填
array· min 1

要轉成請款單的成本列 ID 清單,至少一筆

payeeType必填
enum
supplierguidestaff_commissionother

受款人類型:supplier(供應商)/ guide(領隊)/ staff_commission(員工佣金)/ other(其他)

payeeName必填
string· min 1

受款人姓名/戶名(必填)

payeeBankAccount選填
string

受款人銀行帳號

payeeBankName選填
string

受款人銀行名稱

payeeTaxId選填
string

受款人統一編號/稅籍編號

submitImmediately選填
boolean

設為 true 時建立後立即送出核簽,否則僅存為草稿

回應欄位 · data

ok
boolean
payableId
string
payableNumber
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/payables \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "costIds": [],
    "payeeType": "supplier",
    "payeeName": "<payeeName>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "payableId": "…",
    "payableNumber": "…"
  }
}

新增餐食紀錄

POST/api/v1/departures/{depId}/prep/catering
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

supplier選填
string

餐食供應商名稱

mealPlan選填
string

餐食安排說明(如餐數、菜色)

headcountNote選填
string

人數備註(如素食、特殊餐需求)

status選填
string

餐食安排狀態,預設 pending

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

更新餐食紀錄

PATCH/api/v1/departures/{depId}/prep/catering/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

餐食紀錄 ID

supplier選填
string

餐食供應商名稱

mealPlan選填
string

餐食安排說明(如餐數、菜色)

headcountNote選填
string

人數備註(如素食、特殊餐需求)

status選填
string

餐食安排狀態

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

刪除餐食紀錄

DELETE/api/v1/departures/{depId}/prep/catering/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

餐食紀錄 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/catering/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

設定行前總檢查某項勾選狀態

POST/api/v1/departures/{depId}/prep/checklist
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

itemKey必填
string· min 1

行前檢查項目的代碼

checked必填
boolean

該檢查項目是否已完成勾選

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/checklist \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "itemKey": "<itemKey>",
    "checked": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

設定梯次期限警戒

POST/api/v1/departures/{depId}/prep/deadlines
departure_prep.manage模組:climbing

參數

depId路徑
string· min 1

梯次 ID

permitApply選填
string

入山申請截止日(ISO 日期);傳空字串或省略則清除此期限

permitDownload選填
string

入山證下載截止日(ISO 日期);傳空字串或省略則清除此期限

climbingInsurance選填
string

登山險送保截止日(ISO 日期);傳空字串或省略則清除此期限

liabilityInsurance選填
string

旅責險送保截止日(ISO 日期);傳空字串或省略則清除此期限

回應欄位 · data

permitApply
string | null
permitDownload
string | null
climbingInsurance
string | null
liabilityInsurance
string | null
ok
boolean
departureId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/deadlines \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "permitApply": "…",
    "permitDownload": "…",
    "climbingInsurance": "…",
    "liabilityInsurance": "…",
    "ok": true,
    "departureId": "…"
  }
}

upsert 一種證件追蹤狀態

POST/api/v1/departures/{depId}/prep/documents
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

docType必填
string· min 1

證件/文件種類代碼(如入山申請、保險名冊)

applyStatus選填
enum
todoapplyingapproved

申辦狀態:todo(待辦)/ applying(申請中)/ approved(已核准)

fileReady選填
boolean

文件檔案是否已備妥

uploadedToCloud選填
boolean

文件是否已上傳雲端

fileUri選填
string

文件檔案連結;給 null 清空

note選填
string

備註;給 null 清空

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/documents \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "docType": "<docType>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

upsert 某裝備品項的需求數

POST/api/v1/departures/{depId}/prep/equipment-needs
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

equipmentItemId必填
string· min 1

裝備品項 ID

quantity必填
integer

該品項的需求數量

note選填
string

需求備註;給 null 清空

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/equipment-needs \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "equipmentItemId": "<equipmentItemId>",
    "quantity": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

刪除裝備需求列

DELETE/api/v1/departures/{depId}/prep/equipment-needs/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

裝備需求列 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/equipment-needs/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

指派 / 重派領隊到梯次

POST/api/v1/departures/{depId}/prep/guides
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

guideId必填
string· min 1

領隊 ID

role必填
enum
leaderassistant

指派角色:leader(領隊)或 assistant(隨隊/助理)

status選填
enum
tentativeconfirmed

指派狀態:tentative(暫定)或 confirmed(已確認)

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/guides \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "guideId": "<guideId>",
    "role": "leader"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

新增投保紀錄

POST/api/v1/departures/{depId}/prep/insurance
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

kind必填
string· min 1

保險種類(如登山險、旅責險)

insurer選填
string

保險公司名稱

policyNo選填
string

保單號碼

status選填
string

投保狀態,預設 pending

note選填
string

備註;給 null 清空

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "<kind>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

更新投保紀錄

PATCH/api/v1/departures/{depId}/prep/insurance/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

投保紀錄 ID

insurer選填
string

保險公司名稱

policyNo選填
string

保單號碼

status選填
string

投保狀態

note選填
string

備註;給 null 清空

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

刪除投保紀錄

DELETE/api/v1/departures/{depId}/prep/insurance/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

投保紀錄 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/insurance/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

從裝備需求開租借單

POST/api/v1/departures/{depId}/prep/rentals
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

orderId必填
string· min 1

要掛這筆租借費用的訂單 ID

renterName選填
string

租借人姓名;給 null 清空

lines必填
array

租借品項明細(品項 + 數量),數量需大於 0 才計入

回應欄位 · data

ok
boolean
rentalId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/rentals \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "<orderId>",
    "lines": []
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "rentalId": "…"
  }
}

新增派車紀錄

POST/api/v1/departures/{depId}/prep/transport
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

description選填
string

派車說明(如路線、接送地點)

driverName選填
string

司機姓名

vehicleInfo選填
string

車輛資訊(如車型、車牌)

fareNote選填
string

車資備註

status選填
string

派車狀態,預設 pending

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

更新派車紀錄

PATCH/api/v1/departures/{depId}/prep/transport/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

派車紀錄 ID

description選填
string

派車說明(如路線、接送地點)

driverName選填
string

司機姓名

vehicleInfo選填
string

車輛資訊(如車型、車牌)

fareNote選填
string

車資備註

status選填
string

派車狀態

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

刪除派車紀錄

DELETE/api/v1/departures/{depId}/prep/transport/{id}
departure_prep.manage

參數

depId路徑
string· min 1

梯次 ID

id路徑
string· min 1

派車紀錄 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/<depId>/prep/transport/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

分房表匯出資料列

GET/api/v1/departures/{depId}/rooming-export
departure.update

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data[]

fullName
string
gender
string
roomLabel
string
bedInfo
string
roommates
string
specialRequest
string
contactSummary
string
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooming-export \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "fullName": "…",
      "gender": "…",
      "roomLabel": "…",
      "bedInfo": "…",
      "roommates": "…",
      "specialRequest": "…",
      "contactSummary": "…"
    }
  ]
}

該梯次分房檢視

GET/api/v1/departures/{depId}/rooms
departure.update

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data

departure
object
id
string
departureDate
string
returnDate
string
tripTitle
string
tripSlug
string
capacity
number
bookedCount
number
rooms
object[]
id
string
roomLabel
string
roomType
string
bedCount
number
bedConfig
string | null
accommodationName
string | null
accommodationDate
string | null
baseCostTwd
number
upgradeFeeTwd
number
notes
string | null
departureLodgingId
string | null
assignedTravelers
object[]
unassignedTravelers
object[]
id
string
fullName
string
orderId
string
orderNumber
string
isPrimary
boolean
gender
string | null
birthDate選填
string | undefined
roomPreference
string | null
roommatePref
string | null
stats
object
totalTravelers
number
assignedCount
number
roomCount
number
totalUpgradeFee
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooms \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "departure": {
      "id": "…",
      "departureDate": "…",
      "returnDate": "…",
      "tripTitle": "…",
      "tripSlug": "…",
      "capacity": 0,
      "bookedCount": 0
    },
    "rooms": [
      {
        "id": "…",
        "roomLabel": "…",
        "roomType": "…",
        "bedCount": 0,
        "bedConfig": "…",
        "accommodationName": "…",
        "accommodationDate": "…",
        "baseCostTwd": 0,
        "upgradeFeeTwd": 0,
        "notes": "…",
        "departureLodgingId": "…",
        "assignedTravelers": []
      }
    ],
    "unassignedTravelers": [
      {
        "id": "…",
        "fullName": "…",
        "orderId": "…",
        "orderNumber": "…",
        "isPrimary": true,
        "gender": "…",
        "birthDate": "…",
        "roomPreference": "…",
        "roommatePref": "…"
      }
    ],
    "stats": {
      "totalTravelers": 0,
      "assignedCount": 0,
      "roomCount": 0,
      "totalUpgradeFee": 0
    }
  }
}

建立一間梯次房間

POST/api/v1/departures/{depId}/rooms
departure.update

參數

depId路徑
string· min 1

梯次 ID

roomLabel必填
string· min 1

房間代號/標籤(如 101、A 房)

roomType必填
string· min 1

房型(如 雙人房、四人房)

bedCount必填
integer

床位數,必須大於 0

bedConfig選填
string

床型配置說明(如 2 大床、1 大 2 小)

accommodationName選填
string

住宿地點/旅宿名稱

accommodationDate選填
string

入住日期(ISO 日期字串)

baseCostTwd選填
integer

房間基本成本(台幣),預設 0

upgradeFeeTwd選填
integer

房型升等補款金額(台幣),預設 0

notes選填
string

房間備註

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/rooms \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "roomLabel": "<roomLabel>",
    "roomType": "<roomType>",
    "bedCount": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

編輯房間

PATCH/api/v1/departures/{depId}/rooms/{roomId}
departure.update

參數

roomId路徑
string· min 1

房間 ID

roomLabel選填
string

房間代號/標籤;未給則不變

roomType選填
string

房型;未給則不變

bedCount選填
integer

床位數;未給則不變

bedConfig選填
string

床型配置說明;給 null 清空、未給則不變

accommodationName選填
string

住宿地點名稱;給 null 清空、未給則不變

accommodationDate選填
string

入住日期(ISO 字串);給 null 清空、未給則不變

baseCostTwd選填
integer

房間基本成本(台幣);未給則不變

upgradeFeeTwd選填
integer

房型升等補款金額(台幣);未給則不變

notes選填
string

房間備註;給 null 清空、未給則不變

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/departures/{depId}/rooms/<roomId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

刪除房間

DELETE/api/v1/departures/{depId}/rooms/{roomId}
departure.update

參數

roomId路徑
string· min 1

房間 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/departures/{depId}/rooms/<roomId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

線控確認 auto-pair 建議分組:

POST/api/v1/departures/{depId}/rooms/auto-pair-apply
departure.update

參數

depId路徑
string· min 1

梯次 ID

travelerIds必填
array· min 1

要編入同一房的旅客 ID 清單,至少一人

roomType選填
string· min 1

建立房間的房型,預設 shared(合住)

回應欄位 · data

ok
boolean
roomId
string
travelerIds
string[]
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/rooms/auto-pair-apply \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "travelerIds": []
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "roomId": "…",
    "travelerIds": [
      "…"
    ]
  }
}

對某梯次「尚未排房」的旅客

GET/api/v1/departures/{depId}/rooms/auto-pair-preview
departure.update

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data

suggestion
object
groups
object[]
unmatched
object[]
names
object
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/rooms/auto-pair-preview \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "suggestion": {
      "groups": [],
      "unmatched": []
    },
    "names": "…"
  }
}

該梯次套用的成本範本列

GET/api/v1/departures/{depId}/template-costs
departure.update

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data[]

id
string
category
string
vendorName
string | null
description
string | null
amountTwd
number
invoiceAmountTwd
number
isDeclarable
boolean
quantityMode
QuantityMode | null
headcountComponents
HeadcountComponent[] | null
groupDivisor
number | null
quantity
number | null
unitPriceTwd
number | null
isManualOverride
boolean
payableId
string | null
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/template-costs \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "category": "…",
      "vendorName": "…",
      "description": "…",
      "amountTwd": 0,
      "invoiceAmountTwd": 0,
      "isDeclarable": true,
      "quantityMode": null,
      "headcountComponents": null,
      "groupDivisor": 0,
      "quantity": 0,
      "unitPriceTwd": 0,
      "isManualOverride": true,
      "payableId": "…"
    }
  ]
}

重設為範本算法

POST/api/v1/departures/{depId}/template-costs/{id}/clear-override
departure_cost.manage

參數

id路徑
string· min 1

範本成本列 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/{depId}/template-costs/<id>/clear-override \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

線控手改某範本成本列

POST/api/v1/departures/{depId}/template-costs/{id}/override
departure_cost.manage

參數

id路徑
string· min 1

範本成本列 ID

amountTwd必填
integer

手動指定的成本金額(台幣),設定後停止自動重算

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/{depId}/template-costs/<id>/override \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

套用行程綁定範本到本梯次

POST/api/v1/departures/{depId}/template-costs/apply
departure_cost.create

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data

ok
boolean
inserted
number
請求
curl -X POST https://your-tenant.example.com/api/v1/departures/<depId>/template-costs/apply \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "inserted": 0
  }
}

該梯次各訂單旅客資料完整度

GET/api/v1/departures/{depId}/validation-summary
order.read

參數

depId路徑
string· min 1

梯次 ID

回應欄位 · data[]

orderId
string
orderNumber
string
errorCount
number
warningCount
number
incompleteTravelerCount
number
errorTravelerCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/<depId>/validation-summary \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "orderId": "…",
      "orderNumber": "…",
      "errorCount": 0,
      "warningCount": 0,
      "incompleteTravelerCount": 0,
      "errorTravelerCount": 0
    }
  ]
}

團控主列表:以出發日為主軸、彙整 order/付款/同意書

GET/api/v1/departures/control
order.read

參數

range選填
enum
future_60this_monthnext_month

時間視窗:future_60(未來 60 天)/ this_month(本月)/ next_month(下個月),預設不限

trip選填
string

行程 ID,只看該行程的梯次

status選填
string

梯次狀態篩選(如 open / closed)

attention選填
boolean

設為 true 時只回傳付款或同意書有異常、需要關注的梯次

回應欄位 · data[]

id
string
tripId
string
tripTitle
string
tripSlug
string
departureDate
string
returnDate
string
capacity
number
bookedCount
number
status
string
allocationMode
"fcfs" | "lottery"
priceTwd
number
agencyPriceTwd
number | null
promoActive
boolean
promoPriceTwd
number | null
promoAgencyPriceTwd
number | null
daysUntilDeparture
number
travelerCount
number
paidCount
number
pendingCount
number
cancelledCount
number
ordersWithoutConsent
number
codedRevenueTwd
number
discountTotalTwd
number
profitShareTotalTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/departures/control \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "tripId": "…",
      "tripTitle": "…",
      "tripSlug": "…",
      "departureDate": "…",
      "returnDate": "…",
      "capacity": 0,
      "bookedCount": 0,
      "status": "…",
      "allocationMode": "fcfs",
      "priceTwd": 0,
      "agencyPriceTwd": 0,
      "promoActive": true,
      "promoPriceTwd": 0,
      "promoAgencyPriceTwd": 0,
      "daysUntilDeparture": 0,
      "travelerCount": 0,
      "paidCount": 0,
      "pendingCount": 0,
      "cancelledCount": 0,
      "ordersWithoutConsent": 0,
      "codedRevenueTwd": 0,
      "discountTotalTwd": 0,
      "profitShareTotalTwd": 0
    }
  ]
}

多梯次的分房進度統計

GET/api/v1/departures/room-stats
order.read

參數

ids必填
string· min 1

要查詢的梯次 ID 清單,以逗號分隔(例:a,b,c)

請求
curl -X GET "https://your-tenant.example.com/api/v1/departures/room-stats?ids=<ids>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {}
}

/discount-codes

list all discount codes

GET/api/v1/discount-codes
discount.read

回應欄位 · data[]

id
string
code
string
label
string
discountType
DiscountType
discountValue
number
profitShareType
ProfitShareType | null
profitShareValue
number | null
profitSharePayee
string | null
isActive
boolean
validFrom
Date | null
validUntil
Date | null
maxRedemptions
number | null
redemptionCount
number
minOrderTwd
number | null
appliesToAll
boolean
maxRedemptionsPerCustomer
number | null
allowedPriceChannels
string[] | null
allowedCustomerTypes
string[] | null
stackable
boolean
notes
string | null
createdAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/discount-codes \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "label": "…",
      "discountType": "…",
      "discountValue": 0,
      "profitShareType": null,
      "profitShareValue": 0,
      "profitSharePayee": "…",
      "isActive": true,
      "validFrom": null,
      "validUntil": null,
      "maxRedemptions": 0,
      "redemptionCount": 0,
      "minOrderTwd": 0,
      "appliesToAll": true,
      "maxRedemptionsPerCustomer": 0,
      "allowedPriceChannels": "…",
      "allowedCustomerTypes": "…",
      "stackable": true,
      "notes": "…",
      "createdAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

create a discount code

POST/api/v1/discount-codes
discount.manage

參數

code必填
string· max 64 · min 1

折扣碼字串(前台結帳輸入,不分大小寫須唯一)

label必填
string· max 200 · min 1

折扣碼顯示名稱(後台與報表辨識用)

discountType必填
enum
fixedpercentage

折抵方式:fixed 固定金額(TWD)或 percentage 百分比

discountValue必填
integer

折抵數值;fixed 為折抵金額(TWD),percentage 為百分比(1–100)

profitShareType選填
enum
fixedpercentage

分潤方式:fixed 固定金額或 percentage 百分比;null 為不分潤

profitShareValue選填
integer

分潤數值;搭配 profitShareType,percentage 須 1–100,null 為不分潤

profitSharePayee選填
string· max 200

分潤對象名稱(如合作推廣者),供出款對帳辨識

isActive選填
boolean

是否啟用;停用後前台無法套用

validFrom選填
string

生效起日(YYYY-MM-DD);留空為不限起日

validUntil選填
string

生效迄日(YYYY-MM-DD);留空為不限迄日

maxRedemptions選填
integer

全碼可使用總次數上限;null 為不限

minOrderTwd選填
integer

最低訂單金額門檻(TWD),未達門檻不可套用;null 為不限

appliesToAll選填
boolean

是否適用全部行程;true 時忽略 tripIds

tripIds選填
array

指定可套用的行程 id 清單(appliesToAll=false 時生效)

maxRedemptionsPerCustomer選填
integer

每位客戶可使用次數上限;null 為不限

allowedPriceChannels選填
array

可套用的價格渠道(direct 直客 / agency 同業 / promo 優惠);空陣列為不限

allowedCustomerTypes選填
array

可套用的客戶類型(direct 直客 / agency_contact 同業聯絡人);空陣列為不限

stackable選填
boolean

是否可與其他折扣碼疊加使用

notes選填
string· max 2000

內部備註(不對外顯示)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/discount-codes \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "label": "<label>",
    "discountType": "fixed",
    "discountValue": 0
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

full discount code detail

GET/api/v1/discount-codes/{id}
discount.read

參數

id路徑
string· min 1

折扣碼 id(路徑參數)

回應欄位 · data

id
string
code
string
label
string
discountType
DiscountType
discountValue
number
profitShareType
ProfitShareType | null
profitShareValue
number | null
profitSharePayee
string | null
isActive
boolean
validFrom
Date | null
validUntil
Date | null
maxRedemptions
number | null
redemptionCount
number
minOrderTwd
number | null
appliesToAll
boolean
maxRedemptionsPerCustomer
number | null
allowedPriceChannels
string[] | null
allowedCustomerTypes
string[] | null
stackable
boolean
notes
string | null
createdAt
Date
tripIds
string[]
redemptions
object[]
orderId
string
orderNumber
string
codeSnapshot
string
originalTotalTwd
number
discountTwd
number
profitShareTwd
number
orderStatus
string
createdAt
Date
totalDiscountTwd
number
totalProfitShareTwd
number
totalPaidTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/discount-codes/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "code": "…",
    "label": "…",
    "discountType": "…",
    "discountValue": 0,
    "profitShareType": null,
    "profitShareValue": 0,
    "profitSharePayee": "…",
    "isActive": true,
    "validFrom": null,
    "validUntil": null,
    "maxRedemptions": 0,
    "redemptionCount": 0,
    "minOrderTwd": 0,
    "appliesToAll": true,
    "maxRedemptionsPerCustomer": 0,
    "allowedPriceChannels": "…",
    "allowedCustomerTypes": "…",
    "stackable": true,
    "notes": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "tripIds": [
      "…"
    ],
    "redemptions": [
      {
        "orderId": "…",
        "orderNumber": "…",
        "codeSnapshot": "…",
        "originalTotalTwd": 0,
        "discountTwd": 0,
        "profitShareTwd": 0,
        "orderStatus": "…",
        "createdAt": "2026-06-30T08:00:00.000Z"
      }
    ],
    "totalDiscountTwd": 0,
    "totalProfitShareTwd": 0,
    "totalPaidTwd": 0
  }
}

update a discount code

PATCH/api/v1/discount-codes/{id}
discount.manage

參數

id路徑
string· min 1

折扣碼 id(路徑參數)

code必填
string· max 64 · min 1

折扣碼字串(前台結帳輸入,不分大小寫須唯一)

label必填
string· max 200 · min 1

折扣碼顯示名稱(後台與報表辨識用)

discountType必填
enum
fixedpercentage

折抵方式:fixed 固定金額(TWD)或 percentage 百分比

discountValue必填
integer

折抵數值;fixed 為折抵金額(TWD),percentage 為百分比(1–100)

profitShareType選填
enum
fixedpercentage

分潤方式:fixed 固定金額或 percentage 百分比;null 為不分潤

profitShareValue選填
integer

分潤數值;搭配 profitShareType,percentage 須 1–100,null 為不分潤

profitSharePayee選填
string· max 200

分潤對象名稱(如合作推廣者),供出款對帳辨識

isActive選填
boolean

是否啟用;停用後前台無法套用

validFrom選填
string

生效起日(YYYY-MM-DD);留空為不限起日

validUntil選填
string

生效迄日(YYYY-MM-DD);留空為不限迄日

maxRedemptions選填
integer

全碼可使用總次數上限;null 為不限

minOrderTwd選填
integer

最低訂單金額門檻(TWD),未達門檻不可套用;null 為不限

appliesToAll選填
boolean

是否適用全部行程;true 時忽略 tripIds

tripIds選填
array

指定可套用的行程 id 清單(appliesToAll=false 時生效)

maxRedemptionsPerCustomer選填
integer

每位客戶可使用次數上限;null 為不限

allowedPriceChannels選填
array

可套用的價格渠道(direct 直客 / agency 同業 / promo 優惠);空陣列為不限

allowedCustomerTypes選填
array

可套用的客戶類型(direct 直客 / agency_contact 同業聯絡人);空陣列為不限

stackable選填
boolean

是否可與其他折扣碼疊加使用

notes選填
string· max 2000

內部備註(不對外顯示)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/discount-codes/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "label": "<label>",
    "discountType": "fixed",
    "discountValue": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

redemption/profit-share report for

GET/api/v1/discount-codes/{id}/redemptions
discount.read

參數

id路徑
string· min 1

折扣碼 id(路徑參數)

回應欄位 · data

id
string
code
string
label
string
redemptionCount
number
totalDiscountTwd
number
totalProfitShareTwd
number
totalPaidTwd
number
redemptions
object[]
orderId
string
orderNumber
string
codeSnapshot
string
originalTotalTwd
number
discountTwd
number
profitShareTwd
number
orderStatus
string
createdAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/discount-codes/<id>/redemptions \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "code": "…",
    "label": "…",
    "redemptionCount": 0,
    "totalDiscountTwd": 0,
    "totalProfitShareTwd": 0,
    "totalPaidTwd": 0,
    "redemptions": [
      {
        "orderId": "…",
        "orderNumber": "…",
        "codeSnapshot": "…",
        "originalTotalTwd": 0,
        "discountTwd": 0,
        "profitShareTwd": 0,
        "orderStatus": "…",
        "createdAt": "2026-06-30T08:00:00.000Z"
      }
    ]
  }
}

activate / deactivate a discount

POST/api/v1/discount-codes/{id}/set-active
discount.manage

參數

id路徑
string· min 1

折扣碼 id(路徑參數)

isActive必填
boolean

目標啟用狀態:true 啟用、false 停用

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/discount-codes/<id>/set-active \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

read-only checkout preview of a code's

GET/api/v1/discount-codes/preview
discount.read

參數

code必填
string· min 1

欲試算的折扣碼字串

kind必填
enum
tourlodging

產品種類:tour 行程或 lodging 住宿

tripId選填
string

行程 id(kind=tour 時必填)

total必填
integer

試算用原始金額(TWD,未折扣前)

priceChannel選填
string

價格渠道(direct / agency / promo),用於折扣碼資格判定

customerType選填
string

客戶類型(direct / agency_contact),用於折扣碼資格判定

userId選填
string

客戶 user id,用於每客戶使用次數限制判定

請求
curl -X GET "https://your-tenant.example.com/api/v1/discount-codes/preview?code=<code>&kind=<kind>&total=<total>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": "…"
}

/equipment

list the equipment master

GET/api/v1/equipment/items
equipment.read

參數

activeOnly選填
boolean

只列出啟用中(可租借)的品項

回應欄位 · data[]

id
string
name
string
category
string | null
spec
string | null
rentPriceTwd
number
depositTwd
number
totalCount
number
outCount
number
maintenanceCount
number
availableCount
number
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/equipment/items \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…",
      "category": "…",
      "spec": "…",
      "rentPriceTwd": 0,
      "depositTwd": 0,
      "totalCount": 0,
      "outCount": 0,
      "maintenanceCount": 0,
      "availableCount": 0,
      "isActive": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

create a master item

POST/api/v1/equipment/items
equipment.manage

參數

name必填
string· max 200 · min 1

裝備品項名稱

category選填
string· max 50

裝備分類(如帳篷、睡袋;選填)

spec選填
string· max 500

規格說明(如尺寸、型號;選填)

rentPriceTwd選填
integer· min 0

每日租金(台幣)

depositTwd選填
integer· min 0

每件押金(台幣)

totalCount選填
integer· min 0

總庫存數量

maintenanceCount選填
integer· min 0

維修中而不可租借的數量

isActive選填
boolean

是否啟用(可供租借)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/equipment/items \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

single equipment master item detail.

GET/api/v1/equipment/items/{id}
equipment.read

參數

id路徑
string· min 1

裝備品項 ID

回應欄位 · data

id
string
name
string
category
string | null
spec
string | null
rentPriceTwd
number
depositTwd
number
totalCount
number
outCount
number
maintenanceCount
number
availableCount
number
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/equipment/items/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "name": "…",
    "category": "…",
    "spec": "…",
    "rentPriceTwd": 0,
    "depositTwd": 0,
    "totalCount": 0,
    "outCount": 0,
    "maintenanceCount": 0,
    "availableCount": 0,
    "isActive": true,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}

update a master item

PATCH/api/v1/equipment/items/{id}
equipment.manage

參數

id路徑
string· min 1

要更新的裝備品項 ID

name必填
string· max 200 · min 1

裝備品項名稱

category選填
string· max 50

裝備分類(如帳篷、睡袋;選填)

spec選填
string· max 500

規格說明(如尺寸、型號;選填)

rentPriceTwd選填
integer· min 0

每日租金(台幣)

depositTwd選填
integer· min 0

每件押金(台幣)

totalCount選填
integer· min 0

總庫存數量

maintenanceCount選填
integer· min 0

維修中而不可租借的數量

isActive選填
boolean

是否啟用(可供租借)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/equipment/items/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

list rental tickets

GET/api/v1/equipment/rentals
equipment.read

參數

returnState選填
enum
rentedreturnedoverdue

依歸還狀態篩選:rented 在租中、returned 已歸還、overdue 逾期

reconState選填
enum
pendingreconcileddeposit_pending

依驗收結算狀態篩選:pending 待驗收、reconciled 已結算、deposit_pending 待退押金

orderId選填
string

只列出綁定此訂單 ID 的租借單

departureId選填
string

只列出綁定此梯次 ID 的租借單

回應欄位 · data[]

id
string
orderId
string
orderNumber
string | null
departureId
string | null
renterName
string | null
rentStartDate
string | null
rentEndDate
string | null
returnedAt
Date | null
returnState
ReturnState
inspectedAt
Date | null
damageCostTwd
number | null
reconState
ReconState
notes
string | null
createdAt
Date
updatedAt
Date
lines
object[]
id
string
equipmentItemId
string
itemName
string | null
quantity
number
rentPriceTwdSnapshot
number
depositTwdSnapshot
number
returnedQuantity
number | null
rentTotalTwd
number
depositTotalTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "orderId": "…",
      "orderNumber": "…",
      "departureId": "…",
      "renterName": "…",
      "rentStartDate": "…",
      "rentEndDate": "…",
      "returnedAt": null,
      "returnState": "…",
      "inspectedAt": null,
      "damageCostTwd": 0,
      "reconState": "…",
      "notes": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z",
      "lines": [
        {
          "id": "…",
          "equipmentItemId": "…",
          "itemName": "…",
          "quantity": 0,
          "rentPriceTwdSnapshot": 0,
          "depositTwdSnapshot": 0,
          "returnedQuantity": 0
        }
      ],
      "rentTotalTwd": 0,
      "depositTotalTwd": 0
    }
  ]
}

open a rental ticket

POST/api/v1/equipment/rentals
equipment.manage

參數

orderId必填
string· min 1

租借單綁定的訂單 ID(租金與押金會掛入該訂單金流)

departureId選填
string

關聯的梯次 ID(選填)

renterName選填
string· max 100

租借人姓名(選填)

rentStartDate選填
string· 格式限定

租借起始日,格式 YYYY-MM-DD(選填)

rentEndDate選填
string· 格式限定

租借結束日,格式 YYYY-MM-DD(選填)

notes選填
string· max 1000

租借單備註(選填)

lines必填
array· min 1

租借明細清單(至少一筆品項)

回應欄位 · data

rentalId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "<orderId>",
    "lines": []
  }'
回應
{
  "ok": true,
  "data": {
    "rentalId": "…"
  }
}

single rental ticket detail

GET/api/v1/equipment/rentals/{id}
equipment.read

參數

id路徑
string· min 1

租借單 ID

回應欄位 · data

id
string
orderId
string
orderNumber
string | null
departureId
string | null
renterName
string | null
rentStartDate
string | null
rentEndDate
string | null
returnedAt
Date | null
returnState
ReturnState
inspectedAt
Date | null
damageCostTwd
number | null
reconState
ReconState
notes
string | null
createdAt
Date
updatedAt
Date
lines
object[]
id
string
equipmentItemId
string
itemName
string | null
quantity
number
rentPriceTwdSnapshot
number
depositTwdSnapshot
number
returnedQuantity
number | null
rentTotalTwd
number
depositTotalTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "orderId": "…",
    "orderNumber": "…",
    "departureId": "…",
    "renterName": "…",
    "rentStartDate": "…",
    "rentEndDate": "…",
    "returnedAt": null,
    "returnState": "…",
    "inspectedAt": null,
    "damageCostTwd": 0,
    "reconState": "…",
    "notes": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z",
    "lines": [
      {
        "id": "…",
        "equipmentItemId": "…",
        "itemName": "…",
        "quantity": 0,
        "rentPriceTwdSnapshot": 0,
        "depositTwdSnapshot": 0,
        "returnedQuantity": 0
      }
    ],
    "rentTotalTwd": 0,
    "depositTotalTwd": 0
  }
}

flag a single rented ticket

POST/api/v1/equipment/rentals/{id}/mark-overdue
equipment.manage

參數

id路徑
string· min 1

要標記為逾期的租借單 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals/<id>/mark-overdue \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

receive a rental back

POST/api/v1/equipment/rentals/{id}/return
equipment.manage

參數

id路徑
string· min 1

要驗收歸還的租借單 ID

returnedLines必填
array· min 1

各明細的歸還數量清單

damageCostTwd選填
integer· min 0

損壞賠償金額(台幣,選填)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/equipment/rentals/<id>/return \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "returnedLines": []
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the minimal order picker

GET/api/v1/equipment/rentals/order-options
equipment.read

參數

limit選填
integer· max 200

回傳訂單筆數上限(最多 200,預設取最近多筆)

回應欄位 · data[]

orderId
string
orderNumber
string | null
customerName
string | null
請求
curl -X GET https://your-tenant.example.com/api/v1/equipment/rentals/order-options \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "orderId": "…",
      "orderNumber": "…",
      "customerName": "…"
    }
  ]
}

/exchange-rates

list the Bank-of-Taiwan published FX rate board

GET/api/v1/exchange-rates
account_transfer.read

參數

currency選填
string

幣別篩選(ISO 4217 三碼,如 JPY / USD);省略則回傳所有幣別

monthFrom選填
string· 格式限定

起始月份(YYYY-MM,含當月);省略則不設下界

monthTo選填
string· 格式限定

結束月份(YYYY-MM,含當月);省略則不設上界

回應欄位 · data[]

id
string
rateDate
string
currency
string
cashBuy
string | null
cashSell
string | null
spotBuy
string | null
spotSell
string | null
source
ExchangeRateSource
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/exchange-rates \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "rateDate": "…",
      "currency": "…",
      "cashBuy": "…",
      "cashSell": "…",
      "spotBuy": "…",
      "spotSell": "…",
      "source": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

manual FX rate override

PUT/api/v1/exchange-rates/manual
account_transfer.manage

參數

rateDate必填
string· 格式限定

匯率掛牌日期(YYYY-MM-DD),與幣別共同決定覆蓋哪一筆牌價

currency必填
string· 格式限定

幣別(ISO 4217 三碼大寫,如 JPY / USD)

cashBuy選填
string· 格式限定

現金買入匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null

cashSell選填
string· 格式限定

現金賣出匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null

spotBuy選填
string· 格式限定

即期買入匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null

spotSell選填
string· 格式限定

即期賣出匯率(正數最多 6 位小數,以字串表達);四種報價至少填一個,留空傳 null

回應欄位 · data

ok
boolean
id
string
請求
curl -X PUT https://your-tenant.example.com/api/v1/exchange-rates/manual \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rateDate": "<rateDate>",
    "currency": "<currency>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

resolve the canonical "1 foreign unit =

GET/api/v1/exchange-rates/resolve
account_transfer.read

參數

currency必填
string· min 1

要換算的外幣幣別(ISO 4217 三碼,如 JPY / USD)

date必填
string· 格式限定

換算基準日期(YYYY-MM-DD),套用手動優先 + 往前承接的解析規則

quote選填
enum
cash_buycash_sellspot_buyspot_sell

報價類型:cash_buy 現金買入、cash_sell 現金賣出、spot_buy 即期買入、spot_sell 即期賣出;省略預設 spot_sell

回應欄位 · data

currency
string
date
string
quote
"cash_buy" | "cash_sell" | "spot_buy" | "spot_sell"
rate
string | null
請求
curl -X GET "https://your-tenant.example.com/api/v1/exchange-rates/resolve?currency=<currency>&date=<date>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "currency": "…",
    "date": "…",
    "quote": "cash_buy",
    "rate": "…"
  }
}

/group-codes

航空碼對照表

GET/api/v1/group-codes/airlines
group_code.manage

參數

activeOnly選填
enum
truefalse10

傳 true 或 1 時只列出啟用中的航空碼

回應欄位 · data[]

code
string
name
string
isActive
boolean
displayOrder
number
usedCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/group-codes/airlines \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "code": "…",
      "name": "…",
      "isActive": true,
      "displayOrder": 0,
      "usedCount": 0
    }
  ]
}
POST/api/v1/group-codes/airlines
group_code.manage

參數

code必填
string

對照表碼,2–3 碼大寫英數(自動轉大寫)

name必填
string· max 100 · min 1

碼的顯示名稱(如地區或航空公司全名)

isActive選填
boolean

是否啟用(停用後不再供新團號選用)

displayOrder選填
integer· max 9999 · min 0

排序權重,數字越小越前面

回應欄位 · data

ok
boolean
code
string
請求
curl -X POST https://your-tenant.example.com/api/v1/group-codes/airlines \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "code": "…"
  }
}
PATCH/api/v1/group-codes/airlines
group_code.manage

參數

code必填
string

要更新的對照表碼(不可變更碼本身)

name必填
string· max 100 · min 1

碼的顯示名稱(如地區或航空公司全名)

isActive選填
boolean

是否啟用(停用後不再供新團號選用)

displayOrder選填
integer· max 9999 · min 0

排序權重,數字越小越前面

回應欄位 · data

ok
boolean
code
string
請求
curl -X PATCH https://your-tenant.example.com/api/v1/group-codes/airlines \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "code": "…"
  }
}

前綴團號反查多梯次

GET/api/v1/group-codes/departures
group_code.manage

參數

prefix必填
string· min 1

團號前綴,反查同地區同航空的所有梯次(如 26EGTK)

回應欄位 · data[]

id
string
tripId
string
tripTitle
string
tripSlug
string
departureDate
string
groupCode
string
regionCode
string | null
airlineCode
string | null
請求
curl -X GET "https://your-tenant.example.com/api/v1/group-codes/departures?prefix=<prefix>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "tripId": "…",
      "tripTitle": "…",
      "tripSlug": "…",
      "departureDate": "…",
      "groupCode": "…",
      "regionCode": "…",
      "airlineCode": "…"
    }
  ]
}

精確團號反查單一梯次

GET/api/v1/group-codes/departures/{id}
group_code.manage

參數

id路徑
string· min 1

完整團號,反查單一梯次(大小寫不敏感)

回應欄位 · data

id
string
tripId
string
tripTitle
string
tripSlug
string
departureDate
string
groupCode
string
regionCode
string | null
airlineCode
string | null
請求
curl -X GET https://your-tenant.example.com/api/v1/group-codes/departures/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "tripId": "…",
    "tripTitle": "…",
    "tripSlug": "…",
    "departureDate": "…",
    "groupCode": "…",
    "regionCode": "…",
    "airlineCode": "…"
  }
}

地區碼對照表

GET/api/v1/group-codes/regions
group_code.manage

參數

activeOnly選填
enum
truefalse10

傳 true 或 1 時只列出啟用中的地區碼

回應欄位 · data[]

code
string
name
string
isActive
boolean
displayOrder
number
usedCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/group-codes/regions \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "code": "…",
      "name": "…",
      "isActive": true,
      "displayOrder": 0,
      "usedCount": 0
    }
  ]
}
POST/api/v1/group-codes/regions
group_code.manage

參數

code必填
string

對照表碼,2–3 碼大寫英數(自動轉大寫)

name必填
string· max 100 · min 1

碼的顯示名稱(如地區或航空公司全名)

isActive選填
boolean

是否啟用(停用後不再供新團號選用)

displayOrder選填
integer· max 9999 · min 0

排序權重,數字越小越前面

回應欄位 · data

ok
boolean
code
string
請求
curl -X POST https://your-tenant.example.com/api/v1/group-codes/regions \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "code": "…"
  }
}
PATCH/api/v1/group-codes/regions
group_code.manage

參數

code必填
string

要更新的對照表碼(不可變更碼本身)

name必填
string· max 100 · min 1

碼的顯示名稱(如地區或航空公司全名)

isActive選填
boolean

是否啟用(停用後不再供新團號選用)

displayOrder選填
integer· max 9999 · min 0

排序權重,數字越小越前面

回應欄位 · data

ok
boolean
code
string
請求
curl -X PATCH https://your-tenant.example.com/api/v1/group-codes/regions \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "code": "…"
  }
}

/guide-roster

指派 / 重派 guide 到梯次

POST/api/v1/guide-roster/assignments
guide_roster.manage

參數

departureId必填
string· max 64 · min 1

指派的目標梯次 ID

guideId必填
string· max 64 · min 1

被指派的領隊/嚮導 ID

role必填
enum

指派角色(leader 領隊/assistant 隨隊助理)

status必填
enum

指派狀態(tentative 預塞暫定/confirmed 正式確認)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/assignments \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "departureId": "<departureId>",
    "guideId": "<guideId>",
    "role": "<role>",
    "status": "<status>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

移除某筆指派

DELETE/api/v1/guide-roster/assignments/{id}
guide_roster.manage

參數

id路徑
string· max 64 · min 1

要移除的指派紀錄 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/guide-roster/assignments/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

正式確認某筆指派

POST/api/v1/guide-roster/assignments/{id}/confirm
guide_roster.manage

參數

id路徑
string· max 64 · min 1

要正式確認的指派紀錄 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/assignments/<id>/confirm \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

換領隊

POST/api/v1/guide-roster/change-leader
guide_roster.manage

參數

departureId必填
string· max 64 · min 1

要換領隊的目標梯次 ID

fromGuideId選填
string· max 64 · min 1

原領隊嚮導 ID(選填;省略表示該梯次原本無領隊)

toGuideId必填
string· max 64 · min 1

新任領隊嚮導 ID

reason必填
string· max 500 · min 1

換領隊的原因(必填,記入稽核)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/guide-roster/change-leader \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "departureId": "<departureId>",
    "toGuideId": "<toGuideId>",
    "reason": "<reason>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

pre-check whether assigning a guide

GET/api/v1/guide-roster/conflict-check
guide_roster.read

參數

departureId必填
string· min 1

欲指派的目標梯次 ID

guideId必填
string· min 1

欲檢查檔期衝突的領隊/嚮導 ID

請求
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/conflict-check?departureId=<departureId>&guideId=<guideId>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": null
}

schedule conflicts for the selected

GET/api/v1/guide-roster/conflicts
guide_roster.read

參數

month必填
string· 格式限定

查詢月份(YYYY-MM 格式)

回應欄位 · data[]

guideId
string
guideName
string
a
object
departureId
string
tripTitle
string
departureDate
string
returnDate
string
b
object
departureId
string
tripTitle
string
departureDate
string
returnDate
string
請求
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/conflicts?month=<month>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "guideId": "…",
      "guideName": "…",
      "a": {
        "departureId": "…",
        "tripTitle": "…",
        "departureDate": "…",
        "returnDate": "…"
      },
      "b": {
        "departureId": "…",
        "tripTitle": "…",
        "departureDate": "…",
        "returnDate": "…"
      }
    }
  ]
}

the selected month's departures

GET/api/v1/guide-roster/departures
guide_roster.read

參數

month必填
string· 格式限定

查詢月份(YYYY-MM 格式)

includeCancelled選填
boolean

是否一併納入已取消的梯次(預設不納入)

回應欄位 · data[]

id
string
tripId
string
tripTitle
string
departureDate
string
returnDate
string
days
number
capacity
number
bookedCount
number
status
string
assignments
object[]
id
string
guideId
string
guideName
string
role
"leader" | "assistant"
status
"tentative" | "confirmed"
請求
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/departures?month=<month>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "tripId": "…",
      "tripTitle": "…",
      "departureDate": "…",
      "returnDate": "…",
      "days": 0,
      "capacity": 0,
      "bookedCount": 0,
      "status": "…",
      "assignments": [
        {
          "id": "…",
          "guideId": "…",
          "guideName": "…",
          "role": "leader",
          "status": "tentative"
        }
      ]
    }
  ]
}

roster

GET/api/v1/guide-roster/guides
guide_roster.read

參數

month必填
string· 格式限定

查詢月份(YYYY-MM 格式)

includeInactive選填
boolean

是否一併列出已停用的嚮導(預設不列出)

回應欄位 · data[]

id
string
name
string
rosterRole
"leader" | "assistant" | "both"
specialties
string[]
status
string
maxDaysPerMonth
number | null
monthDays
number
monthTrips
number
hasTentative
boolean
availability
Availability
請求
curl -X GET "https://your-tenant.example.com/api/v1/guide-roster/guides?month=<month>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…",
      "rosterRole": "leader",
      "specialties": [
        "…"
      ],
      "status": "…",
      "maxDaysPerMonth": 0,
      "monthDays": 0,
      "monthTrips": 0,
      "hasTentative": true,
      "availability": "…"
    }
  ]
}

/guides

list/search guides

GET/api/v1/guides
guide.read

參數

slug選填
string· min 1

依嚮導公開頁網址代稱(slug)精確查單筆(選填)

status選填
enum
allactiveinactive

嚮導狀態篩選(all 全部/active 啟用/inactive 停用)

q選填
string

關鍵字搜尋(比對嚮導姓名等欄位)

page選填
integer

頁碼(從 1 起算)

pageSize選填
integer· max 200

每頁筆數(上限 200)

請求
curl -X GET https://your-tenant.example.com/api/v1/guides \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": "…"
}

create a guide

POST/api/v1/guides
guide.manage

參數

name必填
string· max 100 · min 1

嚮導/領隊姓名

slug選填
string· 格式限定

公開頁網址代稱(選填,小寫英數與連字號;省略則自動產生)

bio選填
string· max 20000

嚮導簡介/經歷(選填)

avatarUrl選填
string· max 500

大頭照圖片網址(選填,http/https)

specialties選填
string

專長領域(選填,以逗號分隔多項)

yearsExperience選填
integer· max 80 · min 0

帶團年資(年數,0~80;選填)

contactPhone選填
string· max 40

聯絡電話(選填)

contactEmail選填
string · email· max 120

聯絡 Email(選填)

status選填
enum
activeinactive

嚮導狀態(active 啟用/inactive 停用;預設 active)

回應欄位 · data

id
string
slug
string
請求
curl -X POST https://your-tenant.example.com/api/v1/guides \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "slug": "…"
  }
}

single guide detail

GET/api/v1/guides/{id}
guide.read

參數

id路徑
string· min 1

嚮導 ID

回應欄位 · data

id
string
name
string
slug
string
bio
string | null
avatarUrl
string | null
specialties
string[]
yearsExperience
number | null
contactPhone
string | null
contactEmail
string | null
status
GuideStatus
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/guides/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "name": "…",
    "slug": "…",
    "bio": "…",
    "avatarUrl": "…",
    "specialties": [
      "…"
    ],
    "yearsExperience": 0,
    "contactPhone": "…",
    "contactEmail": "…",
    "status": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}

update a guide

PATCH/api/v1/guides/{id}
guide.manage

參數

id路徑
string· min 1

要更新的嚮導 ID

name選填
string· max 100 · min 1

嚮導/領隊姓名(省略則不更動)

slug選填
string· 格式限定

公開頁網址代稱(小寫英數與連字號;省略則不更動)

bio選填
string· max 20000

嚮導簡介/經歷(省略則不更動)

avatarUrl選填
string· max 500

大頭照圖片網址(http/https;省略則不更動)

specialties選填
string

專長領域(以逗號分隔多項;省略則不更動)

yearsExperience選填
integer· max 80 · min 0

帶團年資(年數,0~80;省略則不更動)

contactPhone選填
string· max 40

聯絡電話(省略則不更動)

contactEmail選填
string · email· max 120

聯絡 Email(省略則不更動)

status選填
enum
activeinactive

嚮導狀態(active 啟用/inactive 停用;省略則不更動)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/guides/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

archive a guide

POST/api/v1/guides/{id}/archive
guide.manage

參數

id路徑
string· min 1

要封存(狀態改為停用)的嚮導 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/guides/<id>/archive \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

開通某既有 guide 的嚮導 portal 登入帳號

POST/api/v1/guides/{id}/invite-account
guide.manage

參數

id路徑
string· min 1

要開通登入帳號的嚮導 ID

email必填
string · email· max 120

嚮導 portal 登入帳號的 Email

name必填
string· max 100 · min 1

嚮導帳號的顯示姓名

回應欄位 · data

tempPassword
string
email
string
請求
curl -X POST https://your-tenant.example.com/api/v1/guides/<id>/invite-account \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "<email>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "tempPassword": "…",
    "email": "…"
  }
}

/holidays

per-tenant national-holiday / makeup-workday table

GET/api/v1/holidays
public_holiday.read

參數

year選填
integer· max 9999 · min 1000

篩選的西元年份(1000..9999);省略則回傳所有年份

回應欄位 · data

rows
object[]
date
string
name
string
isWorkday
boolean
請求
curl -X GET https://your-tenant.example.com/api/v1/holidays \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "date": "…",
        "name": "…",
        "isWorkday": true
      }
    ]
  }
}

upsert / delete a single per-tenant

PUT/api/v1/holidays/{date}
public_holiday.manage

參數

date路徑
string· min 1

假日 / 補班日的日期(YYYY-MM-DD,路徑參數),作為該筆紀錄的自然鍵

name必填
string· max 100 · min 1

假日 / 補班日名稱(如「春節」「補行上班」)

isWorkday選填
boolean

是否為補班日:true 表示原假日改上班、false 表示國定假日;影響行前作業工作日倒數

回應欄位 · data

ok
boolean
請求
curl -X PUT https://your-tenant.example.com/api/v1/holidays/<date> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/holidays/{date}
public_holiday.manage

參數

date路徑
string· min 1

要刪除的假日 / 補班日日期(YYYY-MM-DD,路徑參數)

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/holidays/<date> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

holiday / makeup-workday counts for a

GET/api/v1/holidays/stats
public_holiday.read

參數

year必填
integer· max 9999 · min 1000

要統計的西元年份(1000..9999,必填)

回應欄位 · data

holidayCount
number
makeupCount
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/holidays/stats?year=<year>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "holidayCount": 0,
    "makeupCount": 0
  }
}

/images

list/search the trip image gallery

GET/api/v1/images
image.read

參數

tripId選填
string

行程 ID 篩選,僅回傳掛在該行程的圖片

q選填
string

關鍵字,模糊比對行程標題、slug、圖說或網址

page選填
integer

分頁頁碼,從 1 起算,預設第 1 頁

pageSize選填
integer· max 200

每頁筆數,上限 200,預設由後端決定

回應欄位 · data

rows
object[]
id
string
tripId
string
tripTitle
string
tripSlug
string
url
string
caption
string | null
displayOrder
number
createdAt
Date
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/images \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "tripId": "…",
        "tripTitle": "…",
        "tripSlug": "…",
        "url": "…",
        "caption": "…",
        "displayOrder": 0,
        "createdAt": "2026-06-30T08:00:00.000Z"
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}
POST/api/v1/images
image.manage

參數

tripId必填
string· min 1

要掛上此圖片的行程 ID

url必填
string· max 2000

圖片網址(http 或 https),以引用方式掛載,非檔案上傳

caption選填
string· max 500

圖片說明文字,選填

displayOrder選填
integer· max 9999 · min 0

排序權重,數字越小越前面,預設 0

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/images \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tripId": "<tripId>",
    "url": "<url>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

remove a trip image

DELETE/api/v1/images/{id}
image.manage

參數

id路徑
string· min 1

欲刪除的行程圖片 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/images/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the trip picker for attaching images: draft +

GET/api/v1/images/trips
image.read

回應欄位 · data[]

id
string
title
string
請求
curl -X GET https://your-tenant.example.com/api/v1/images/trips \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "title": "…"
    }
  ]
}

/internal-external-ledger

PATCH/api/v1/internal-external-ledger/costs/{costId}
ledger.manage

參數

category必填
string

成本類別代碼(須為有效的成本分類)

vendorName選填
string

廠商/供應商名稱

description選填
string

成本摘要說明

amountTwd選填
integer

真實成本(台幣整數)。台幣路徑必填;外幣路徑忽略,改由外幣金額乘匯率換算

currency選填
string

幣別;TWD 或留空走台幣路徑,其他幣別走外幣路徑

foreignAmount選填
integer

外幣金額(整數);僅外幣路徑使用

internalRateSource選填
enum
fx_accountpublishedmanual

內帳匯率來源:fx_account 外幣帳戶加權成本、published 台銀牌告、manual 手填成交率

fxAccountId選填
string

外幣帳戶 ID;內帳匯率來源為 fx_account 時使用

manualRate選填
string

手填成交匯率(字串保精度);內帳匯率來源為 manual 時使用

hasReceipt選填
boolean

是否有發票憑證;預設 true,false 表示無發票並強制可申報額為 0、改填支出證明單欄位

invoiceAmountTwd選填
integer

外帳可申報額覆寫(台幣整數,須大於等於 0、無上限)

payeeName選填
string

受款人姓名;無發票時的支出證明單欄位

reasonNoReceipt選填
string

無發票原因;無發票時的支出證明單欄位

proofSummary選填
string

支出證明摘要;無發票時的支出證明單欄位

costId路徑
string· min 1

成本列 ID

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "<category>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/internal-external-ledger/costs/{costId}
ledger.manage

參數

costId路徑
string· min 1

成本列 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
POST/api/v1/internal-external-ledger/costs/{costId}/approve-declaration
ledger.approve

參數

costId路徑
string· min 1

成本列 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/costs/<costId>/approve-declaration \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

待覆核的嚮導申報

GET/api/v1/internal-external-ledger/declarations/pending
ledger.read

回應欄位 · data[]

id
string
departureId
string
tripTitle
string
departureDate
string
category
string
vendorName
string | null
amountTwd
number
invoiceAmountTwd
number
isDeclarable
boolean
createdByName
string | null
createdAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/declarations/pending \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "departureId": "…",
      "tripTitle": "…",
      "departureDate": "…",
      "category": "…",
      "vendorName": "…",
      "amountTwd": 0,
      "invoiceAmountTwd": 0,
      "isDeclarable": true,
      "createdByName": "…",
      "createdAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

per-departure 內外帳列表

GET/api/v1/internal-external-ledger/departures
ledger.read

參數

windowDays選填
integer

回看天數;只列出近 N 天內的梯次

tripId選填
string

行程 ID;只列出該行程的梯次

period選填
string· 格式限定

出團月(格式 YYYY-MM);只列出該月的梯次

回應欄位 · data[]

tripTitle
string
tripSlug
string
departureDate
string
returnDate
string
groupCode
string | null
pax
number
departureId
string
revenueTwd
number
realCostTwd
number
declarableCostTwd
number
nonDeclarableCostTwd
number
costBilledTwd
number
costUnbilledTwd
number
grossProfitTwd
number
feeEcpayTwd
number
feeFongshouTwd
number
taxEstTwd
number
estimatedNetProfitTwd
number
marginPct
number | null
pendingProofCount
number
feeRates
object
ecpayFeeBps
number
fongshouFeeBps
number
profitTaxBps
number
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "tripTitle": "…",
      "tripSlug": "…",
      "departureDate": "…",
      "returnDate": "…",
      "groupCode": "…",
      "pax": 0,
      "departureId": "…",
      "revenueTwd": 0,
      "realCostTwd": 0,
      "declarableCostTwd": 0,
      "nonDeclarableCostTwd": 0,
      "costBilledTwd": 0,
      "costUnbilledTwd": 0,
      "grossProfitTwd": 0,
      "feeEcpayTwd": 0,
      "feeFongshouTwd": 0,
      "taxEstTwd": 0,
      "estimatedNetProfitTwd": 0,
      "marginPct": 0,
      "pendingProofCount": 0,
      "feeRates": {
        "ecpayFeeBps": 0,
        "fongshouFeeBps": 0,
        "profitTaxBps": 0
      }
    }
  ]
}

single

GET/api/v1/internal-external-ledger/departures/{departureId}
ledger.read

參數

departureId路徑
string· min 1

梯次 ID

回應欄位 · data

departureId
string
revenueTwd
number
realCostTwd
number
declarableCostTwd
number
nonDeclarableCostTwd
number
costBilledTwd
number
costUnbilledTwd
number
grossProfitTwd
number
feeEcpayTwd
number
feeFongshouTwd
number
taxEstTwd
number
estimatedNetProfitTwd
number
marginPct
number | null
pendingProofCount
number
feeRates
object
ecpayFeeBps
number
fongshouFeeBps
number
profitTaxBps
number
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "departureId": "…",
    "revenueTwd": 0,
    "realCostTwd": 0,
    "declarableCostTwd": 0,
    "nonDeclarableCostTwd": 0,
    "costBilledTwd": 0,
    "costUnbilledTwd": 0,
    "grossProfitTwd": 0,
    "feeEcpayTwd": 0,
    "feeFongshouTwd": 0,
    "taxEstTwd": 0,
    "estimatedNetProfitTwd": 0,
    "marginPct": 0,
    "pendingProofCount": 0,
    "feeRates": {
      "ecpayFeeBps": 0,
      "fongshouFeeBps": 0,
      "profitTaxBps": 0
    }
  }
}
POST/api/v1/internal-external-ledger/departures/{departureId}/convert-to-payable
ledger.manage

參數

departureId路徑
string· min 1

梯次 ID

costIds必填
array· min 1

要轉成請款核簽的成本列 ID 陣列(至少一筆,須為尚未轉請款者)

payeeType選填
enum
supplierguidestaff_commissionother

受款對象類型:supplier 供應商、guide 嚮導、staff_commission 員工佣金、other 其他

payeeName必填
string· min 1

受款對象名稱

payeeBankAccount選填
string

受款銀行帳號

payeeBankName選填
string

受款銀行名稱

payeeBankBranch選填
string

受款銀行分行

payeeTaxId選填
string

受款對象統一編號/稅籍編號

taxAmountTwd選填
integer

代扣稅額(台幣整數)

submitImmediately選填
boolean

是否建立後立即送出核簽(true 直接送審)

回應欄位 · data

payableId
string
payableNumber
string
請求
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/convert-to-payable \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "costIds": [],
    "payeeName": "<payeeName>"
  }'
回應
{
  "ok": true,
  "data": {
    "payableId": "…",
    "payableNumber": "…"
  }
}
GET/api/v1/internal-external-ledger/departures/{departureId}/costs
ledger.read

參數

departureId路徑
string· min 1

梯次 ID

createdBy選填
string

登記者使用者 ID;只列出該人登記的成本列

回應欄位 · data[]

id
string
departureId
string
category
string
vendorName
string | null
description
string | null
amountTwd
number
invoiceAmountTwd
number
isDeclarable
boolean
reviewStatus
string
currency
string
foreignAmount
number | null
internalRateSource
string | null
fxAccountId
string | null
internalRate
string | null
externalRate
string | null
feeCategory
string | null
expenseProofId
string | null
proofNumber
string | null
proofStatus
string | null
payableId
string | null
payableNumber
string | null
payableStatus
string | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/costs \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "departureId": "…",
      "category": "…",
      "vendorName": "…",
      "description": "…",
      "amountTwd": 0,
      "invoiceAmountTwd": 0,
      "isDeclarable": true,
      "reviewStatus": "…",
      "currency": "…",
      "foreignAmount": 0,
      "internalRateSource": "…",
      "fxAccountId": "…",
      "internalRate": "…",
      "externalRate": "…",
      "feeCategory": "…",
      "expenseProofId": "…",
      "proofNumber": "…",
      "proofStatus": "…",
      "payableId": "…",
      "payableNumber": "…",
      "payableStatus": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/internal-external-ledger/departures/{departureId}/costs
ledger.manage

參數

category必填
string

成本類別代碼(須為有效的成本分類)

vendorName選填
string

廠商/供應商名稱

description選填
string

成本摘要說明

amountTwd選填
integer

真實成本(台幣整數)。台幣路徑必填;外幣路徑忽略,改由外幣金額乘匯率換算

currency選填
string

幣別;TWD 或留空走台幣路徑,其他幣別走外幣路徑

foreignAmount選填
integer

外幣金額(整數);僅外幣路徑使用

internalRateSource選填
enum
fx_accountpublishedmanual

內帳匯率來源:fx_account 外幣帳戶加權成本、published 台銀牌告、manual 手填成交率

fxAccountId選填
string

外幣帳戶 ID;內帳匯率來源為 fx_account 時使用

manualRate選填
string

手填成交匯率(字串保精度);內帳匯率來源為 manual 時使用

hasReceipt選填
boolean

是否有發票憑證;預設 true,false 表示無發票並強制可申報額為 0、改填支出證明單欄位

invoiceAmountTwd選填
integer

外帳可申報額覆寫(台幣整數,須大於等於 0、無上限)

payeeName選填
string

受款人姓名;無發票時的支出證明單欄位

reasonNoReceipt選填
string

無發票原因;無發票時的支出證明單欄位

proofSummary選填
string

支出證明摘要;無發票時的支出證明單欄位

departureId路徑
string· min 1

梯次 ID

回應欄位 · data

id
string
expenseProofId
string | null
請求
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/costs \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "<category>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "expenseProofId": "…"
  }
}

支出

GET/api/v1/internal-external-ledger/departures/{departureId}/proofs
ledger.read

參數

departureId路徑
string· min 1

梯次 ID

回應欄位 · data[]

id
string
proofNumber
string
departureId
string
payeeName
string
amountTwd
number
reasonNoReceipt
string
summary
string | null
handlerUserId
string
approverUserId
string | null
status
ExpenseProofStatus
approvedAt
Date | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/proofs \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "proofNumber": "…",
      "departureId": "…",
      "payeeName": "…",
      "amountTwd": 0,
      "reasonNoReceipt": "…",
      "summary": "…",
      "handlerUserId": "…",
      "approverUserId": "…",
      "status": "…",
      "approvedAt": null,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
GET/api/v1/internal-external-ledger/departures/{departureId}/proofs/{proofId}
ledger.read

參數

departureId路徑
string· min 1

梯次 ID

proofId路徑
string· min 1

支出證明單 ID

回應欄位 · data

id
string
proofNumber
string
departureId
string
payeeName
string
amountTwd
number
reasonNoReceipt
string
summary
string | null
handlerUserId
string
approverUserId
string | null
status
ExpenseProofStatus
approvedAt
Date | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/internal-external-ledger/departures/<departureId>/proofs/<proofId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "proofNumber": "…",
    "departureId": "…",
    "payeeName": "…",
    "amountTwd": 0,
    "reasonNoReceipt": "…",
    "summary": "…",
    "handlerUserId": "…",
    "approverUserId": "…",
    "status": "…",
    "approvedAt": null,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
POST/api/v1/internal-external-ledger/proofs/{proofId}/approve
ledger.approve

參數

proofId路徑
string· min 1

支出證明單 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/internal-external-ledger/proofs/<proofId>/approve \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/journal

list/search 嚮導手記 posts

GET/api/v1/journal
journal.read

參數

status選填
enum
alldraftpublishedarchived

依狀態篩選:all 全部、draft 草稿、published 已發佈、archived 已封存

q選填
string

關鍵字搜尋(標題/內容)

page選填
integer

頁碼(從 1 起)

pageSize選填
integer· max 200

每頁筆數(上限 200)

回應欄位 · data

rows
object[]
id
string
slug
string
title
string
excerpt
string | null
coverImageUrl
string | null
contentMdx
string
authorGuideId
string | null
seoTitle
string | null
seoDescription
string | null
ogImageUrl
string | null
status
JournalStatus
publishedAt
Date | null
createdAt
Date
updatedAt
Date
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/journal \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "slug": "…",
        "title": "…",
        "excerpt": "…",
        "coverImageUrl": "…",
        "contentMdx": "…",
        "authorGuideId": "…",
        "seoTitle": "…",
        "seoDescription": "…",
        "ogImageUrl": "…",
        "status": "…",
        "publishedAt": null,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "updatedAt": "2026-06-30T08:00:00.000Z"
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}

create a 嚮導手記 post

POST/api/v1/journal
journal.manage

參數

title必填
string· max 200 · min 1

手記標題,顯示於前台與後台列表

slug選填
string· 格式限定

網址代稱(slug);僅小寫英數與連字號,省略時由系統依標題產生

excerpt選填
string· max 1000

摘要,列表與分享預覽用;null 清除

coverImageUrl選填
string· max 500

封面圖網址(http/https);null 清除

contentMdx必填
string· max 100000 · min 1

內文(MDX 格式)

authorGuideId選填
string

作者嚮導 ID;null 表示無指定作者

seoTitle選填
string· max 200

SEO 標題,省略時用 title;null 清除

seoDescription選填
string· max 500

SEO 描述(meta description);null 清除

ogImageUrl選填
string· max 500

Open Graph 分享圖網址(http/https);null 清除

status選填
enum
draftpublishedarchived

發佈狀態:draft 草稿、published 已發佈、archived 已封存

回應欄位 · data

id
string
slug
string
請求
curl -X POST https://your-tenant.example.com/api/v1/journal \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "<title>",
    "contentMdx": "<contentMdx>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "slug": "…"
  }
}

full 嚮導手記 post detail

GET/api/v1/journal/{id}
journal.read

參數

id路徑
string· min 1

嚮導手記文章 ID

回應欄位 · data

id
string
slug
string
title
string
excerpt
string | null
coverImageUrl
string | null
contentMdx
string
authorGuideId
string | null
seoTitle
string | null
seoDescription
string | null
ogImageUrl
string | null
status
JournalStatus
publishedAt
Date | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/journal/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "slug": "…",
    "title": "…",
    "excerpt": "…",
    "coverImageUrl": "…",
    "contentMdx": "…",
    "authorGuideId": "…",
    "seoTitle": "…",
    "seoDescription": "…",
    "ogImageUrl": "…",
    "status": "…",
    "publishedAt": null,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}

update a 嚮導手記 post

PATCH/api/v1/journal/{id}
journal.manage

參數

title必填
string· max 200 · min 1

手記標題,顯示於前台與後台列表

slug選填
string· 格式限定

網址代稱(slug);僅小寫英數與連字號,省略時由系統依標題產生

excerpt選填
string· max 1000

摘要,列表與分享預覽用;null 清除

coverImageUrl選填
string· max 500

封面圖網址(http/https);null 清除

contentMdx必填
string· max 100000 · min 1

內文(MDX 格式)

authorGuideId選填
string

作者嚮導 ID;null 表示無指定作者

seoTitle選填
string· max 200

SEO 標題,省略時用 title;null 清除

seoDescription選填
string· max 500

SEO 描述(meta description);null 清除

ogImageUrl選填
string· max 500

Open Graph 分享圖網址(http/https);null 清除

status選填
enum
draftpublishedarchived

發佈狀態:draft 草稿、published 已發佈、archived 已封存

id路徑
string· min 1

嚮導手記文章 ID

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/journal/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "<title>",
    "contentMdx": "<contentMdx>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

archive a 嚮導手記 post

POST/api/v1/journal/{id}/archive
journal.manage

參數

id路徑
string· min 1

嚮導手記文章 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/journal/<id>/archive \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

active guides as author options for journal

GET/api/v1/journal/authors
journal.read

回應欄位 · data[]

value
string
label
string
請求
curl -X GET https://your-tenant.example.com/api/v1/journal/authors \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "value": "…",
      "label": "…"
    }
  ]
}

/leaderboard

全公司業務業績排行

GET/api/v1/leaderboard
leaderboard.read

參數

period選填
enum
monthquarteryearall

業績統計區間:當月、當季、當年或全部,預設 month

回應欄位 · data[]

userId
string
name
string
email
string
role
string
orderCount
number
paidCount
number
cancelledCount
number
revenue
number
請求
curl -X GET https://your-tenant.example.com/api/v1/leaderboard \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "userId": "…",
      "name": "…",
      "email": "…",
      "role": "…",
      "orderCount": 0,
      "paidCount": 0,
      "cancelledCount": 0,
      "revenue": 0
    }
  ]
}

待派發訂單 KPI

GET/api/v1/leaderboard/review-stats
leaderboard.read

回應欄位 · data

pendingCount
number
pendingTotalTwd
number
longestWaitHours
number
thisMonthAssigned
number
請求
curl -X GET https://your-tenant.example.com/api/v1/leaderboard/review-stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "pendingCount": 0,
    "pendingTotalTwd": 0,
    "longestWaitHours": 0,
    "thisMonthAssigned": 0
  }
}

/lodging

list staff-side direct lodging bookings

GET/api/v1/lodging/bookings
lodging.read

參數

status選填
string

依訂單狀態篩選(省略則回全部)

q選填
string

自由文字關鍵字(訂房人、旅宿等)

回應欄位 · data[]

orderId
string
orderNumber
string
status
string
bookingState
string
paymentState
string
refundState
string
totalTwd
number
createdAt
Date
bookerName
string
bookerEmail
string
propertyId
string
propertyName
string
roomTypeId
string
roomTypeName
string
checkIn
string
checkOut
string
units
number
guestCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/bookings \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "orderId": "…",
      "orderNumber": "…",
      "status": "…",
      "bookingState": "…",
      "paymentState": "…",
      "refundState": "…",
      "totalTwd": 0,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "bookerName": "…",
      "bookerEmail": "…",
      "propertyId": "…",
      "propertyName": "…",
      "roomTypeId": "…",
      "roomTypeName": "…",
      "checkIn": "…",
      "checkOut": "…",
      "units": 0,
      "guestCount": 0
    }
  ]
}
POST/api/v1/lodging/bookings
order.create模組:lodging

參數

propertyId必填
string· min 1

旅宿物件 ID

roomTypeId必填
string· min 1

房型 ID(須屬於該旅宿物件)

checkIn必填
string· min 1

入住日(YYYY-MM-DD,含此晚)

checkOut必填
string· min 1

退房日(YYYY-MM-DD,不含此晚,須晚於入住日)

units必填
integer

預訂單元數(房數或床位數,1-50)

guestCount必填
integer

入住人數(1-100,不得超過房型總容納人數)

bookerEmail必填
string· min 1

訂房人 Email(須為已註冊會員)

paymentMethod必填
enum
cashatmmanual

付款方式:cash 現金/atm 轉帳/manual 其他人工

receivingAccountId選填
string

收款帳戶 ID(搭配付款方式記帳,可省略)

notes選填
string

代訂備註

回應欄位 · data

orderId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/bookings \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyId": "<propertyId>",
    "roomTypeId": "<roomTypeId>",
    "checkIn": "<checkIn>",
    "checkOut": "<checkOut>",
    "units": 0,
    "guestCount": 0,
    "bookerEmail": "<bookerEmail>",
    "paymentMethod": "cash"
  }'
回應
{
  "ok": true,
  "data": {
    "orderId": "…"
  }
}

single lodging booking detail.

GET/api/v1/lodging/bookings/{orderId}
lodging.read

參數

orderId路徑
string· min 1

旅宿訂單 ID

回應欄位 · data

orderId
string
orderNumber
string
status
string
bookingState
string
paymentState
string
refundState
string
totalTwd
number
createdAt
Date
bookerName
string
bookerEmail
string
propertyId
string
propertyName
string
roomTypeId
string
roomTypeName
string
checkIn
string
checkOut
string
units
number
guestCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/bookings/<orderId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "orderId": "…",
    "orderNumber": "…",
    "status": "…",
    "bookingState": "…",
    "paymentState": "…",
    "refundState": "…",
    "totalTwd": 0,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "bookerName": "…",
    "bookerEmail": "…",
    "propertyId": "…",
    "propertyName": "…",
    "roomTypeId": "…",
    "roomTypeName": "…",
    "checkIn": "…",
    "checkOut": "…",
    "units": 0,
    "guestCount": 0
  }
}

cancel a direct lodging

POST/api/v1/lodging/bookings/{orderId}/cancel
order.update

參數

orderId路徑
string· min 1

旅宿訂單 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/bookings/<orderId>/cancel \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

delete a gallery

DELETE/api/v1/lodging/images/{id}
lodging.manage模組:lodging

參數

id路徑
string· min 1

圖片 ID

kind必填
enum
propertyroom-type

圖片所屬相簿:property 旅宿相簿/room-type 房型相簿

回應欄位 · data

ok
boolean
請求
curl -X DELETE "https://your-tenant.example.com/api/v1/lodging/images/<id>?kind=<kind>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

list tenant lodging properties

GET/api/v1/lodging/properties
lodging.read

回應欄位 · data[]

id
string
description
string | null
status
string
name
string
phone
string | null
kind
string
contentMdx
string | null
slug
string
coverImageUrl
string | null
seoTitle
string | null
seoDescription
string | null
ogImageUrl
string | null
isOverseas
boolean
location
string | null
facilities
unknown
usageHint
string
checkInTime
string | null
checkOutTime
string | null
checkInInfo
string | null
houseRules
string | null
cancellationPolicy
string | null
addressRegion
string | null
addressLocality
string | null
streetAddress
string | null
postalCode
string | null
latitude
number | null
longitude
number | null
petsAllowed
boolean | null
smokingAllowed
boolean | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "description": "…",
      "status": "…",
      "name": "…",
      "phone": "…",
      "kind": "…",
      "contentMdx": "…",
      "slug": "…",
      "coverImageUrl": "…",
      "seoTitle": "…",
      "seoDescription": "…",
      "ogImageUrl": "…",
      "isOverseas": true,
      "location": "…",
      "facilities": "…",
      "usageHint": "…",
      "checkInTime": "…",
      "checkOutTime": "…",
      "checkInInfo": "…",
      "houseRules": "…",
      "cancellationPolicy": "…",
      "addressRegion": "…",
      "addressLocality": "…",
      "streetAddress": "…",
      "postalCode": "…",
      "latitude": 0,
      "longitude": 0,
      "petsAllowed": true,
      "smokingAllowed": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

create a property

POST/api/v1/lodging/properties
lodging.manage模組:lodging

參數

slug必填
string· 格式限定

旅宿代稱(小寫英數與連字號,2-63 字,租戶內唯一,用於網址)

name必填
string· max 200 · min 1

旅宿名稱(對外顯示)

kind選填
enum
camphotel

旅宿類型:camp 營地/hotel 旅館,預設 hotel

isOverseas選填
boolean

是否為海外旅宿,預設否

location選填
string· max 200

所在地點概述(如縣市、區域)

description選填
string· max 2000

旅宿介紹文字

usageHint選填
enum
directpackageboth

銷售用途:direct 僅直接訂房/package 僅併入套裝行程/both 兩者皆可,預設 both

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "<slug>",
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

single lodging property

GET/api/v1/lodging/properties/{id}
lodging.read

參數

id路徑
string· min 1

旅宿物件 ID

回應欄位 · data

id
string
description
string | null
status
string
name
string
phone
string | null
kind
string
contentMdx
string | null
slug
string
coverImageUrl
string | null
seoTitle
string | null
seoDescription
string | null
ogImageUrl
string | null
isOverseas
boolean
location
string | null
facilities
unknown
usageHint
string
checkInTime
string | null
checkOutTime
string | null
checkInInfo
string | null
houseRules
string | null
cancellationPolicy
string | null
addressRegion
string | null
addressLocality
string | null
streetAddress
string | null
postalCode
string | null
latitude
number | null
longitude
number | null
petsAllowed
boolean | null
smokingAllowed
boolean | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "description": "…",
    "status": "…",
    "name": "…",
    "phone": "…",
    "kind": "…",
    "contentMdx": "…",
    "slug": "…",
    "coverImageUrl": "…",
    "seoTitle": "…",
    "seoDescription": "…",
    "ogImageUrl": "…",
    "isOverseas": true,
    "location": "…",
    "facilities": "…",
    "usageHint": "…",
    "checkInTime": "…",
    "checkOutTime": "…",
    "checkInInfo": "…",
    "houseRules": "…",
    "cancellationPolicy": "…",
    "addressRegion": "…",
    "addressLocality": "…",
    "streetAddress": "…",
    "postalCode": "…",
    "latitude": 0,
    "longitude": 0,
    "petsAllowed": true,
    "smokingAllowed": true,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}

update a property

PATCH/api/v1/lodging/properties/{id}
lodging.manage模組:lodging

參數

id路徑
string· min 1

旅宿物件 ID

name選填
string· max 200 · min 1

旅宿名稱(對外顯示)

location選填
string· max 200

所在地點概述(如縣市、區域)

description選填
string· max 2000

旅宿介紹文字

usageHint選填
enum
directpackageboth

銷售用途:direct 僅直接訂房/package 僅併入套裝行程/both 兩者皆可

checkInTime選填
string· max 10

入住時間(如 15:00)

checkOutTime選填
string· max 10

退房時間(如 11:00)

checkInInfo選填
string· max 2000

入住須知與報到說明

houseRules選填
string· max 2000

住宿規範

cancellationPolicy選填
string· max 2000

取消政策說明

addressRegion選填
string· max 50

地址行政區(縣市層級)

addressLocality選填
string· max 50

地址鄉鎮市區

streetAddress選填
string· max 200

街道地址

postalCode選填
string· max 10

郵遞區號

latitude選填
integer· max 90

緯度(-90 至 90)

longitude選填
integer· max 180

經度(-180 至 180)

phone選填
string· max 50

聯絡電話

petsAllowed選填
enum
allowdisallowunset

是否允許攜帶寵物:allow 允許/disallow 不允許/unset 清除設定,省略則不變更

smokingAllowed選填
enum
allowdisallowunset

是否允許吸菸:allow 允許/disallow 不允許/unset 清除設定,省略則不變更

facilities選填
array

設施代碼陣列(須為合法 amenity key;送空陣列代表清空)

seoTitle選填
string

SEO 標題(送空字串代表清空,退回預設)

seoDescription選填
string

SEO 描述(送空字串代表清空,退回預設)

ogImageUrl選填
string

社群分享圖 URL(須為 http/https,送空字串代表清空)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/lodging/properties/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

archive

POST/api/v1/lodging/properties/{id}/archive
lodging.manage模組:lodging

參數

id路徑
string· min 1

旅宿物件 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/archive \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

property gallery images.

GET/api/v1/lodging/properties/{id}/images
lodging.read模組:lodging

參數

id路徑
string· min 1

旅宿物件 ID

回應欄位 · data[]

id
string
url
string
caption
string | null
displayOrder
number
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id>/images \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "url": "…",
      "caption": "…",
      "displayOrder": 0
    }
  ]
}

add a property gallery image

POST/api/v1/lodging/properties/{id}/images
lodging.manage模組:lodging

參數

id路徑
string· min 1

旅宿物件 ID

url必填
string· min 1

圖片網址

caption選填
string

圖片說明文字(可省略)

displayOrder選填
integer

在相簿中的排序序號,數字越小越前面,預設 0

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/images \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "<url>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

room types for one property

GET/api/v1/lodging/properties/{id}/room-types
lodging.read

參數

id路徑
string· min 1

旅宿物件 ID

回應欄位 · data[]

id
string
description
string | null
status
string
name
string
bedConfig
unknown
propertyId
string
facilities
unknown
createdAt
Date
updatedAt
Date
inventoryUnit
string
unitsTotal
number
capacityPerUnit
number
basePriceTwd
number
floorSizeSqm
number | null
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/properties/<id>/room-types \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "description": "…",
      "status": "…",
      "name": "…",
      "bedConfig": "…",
      "propertyId": "…",
      "facilities": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z",
      "inventoryUnit": "…",
      "unitsTotal": 0,
      "capacityPerUnit": 0,
      "basePriceTwd": 0,
      "floorSizeSqm": 0
    }
  ]
}

create a room type under this property

POST/api/v1/lodging/properties/{id}/room-types
lodging.manage模組:lodging

參數

id路徑
string· min 1

所屬旅宿物件 ID

name必填
string· max 200 · min 1

房型名稱(如標準雙人房)

inventoryUnit選填
enum
roombed

庫存單位:room 以房計/bed 以床位計,預設 room

unitsTotal必填
integer· max 10000 · min 1

此房型可售總單元數(房數或床位數)

capacityPerUnit選填
integer· max 100 · min 1

每單元可容納人數,預設 1

basePriceTwd必填
integer· max 10000000 · min 0

每晚每單元基準售價(新台幣)

description選填
string· max 2000

房型介紹文字

floorSizeSqm選填
integer

房間坪數(平方公尺)

bedType選填
string

床型代碼(須為合法 bed type,搭配 bedCount 才生效)

bedCount選填
integer

該床型數量(須大於 0 才生效)

facilities選填
array

房型設施代碼陣列(須為合法 amenity key)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/properties/<id>/room-types \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>",
    "unitsTotal": 0,
    "basePriceTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

single room type

GET/api/v1/lodging/room-types/{id}
lodging.read

參數

id路徑
string· min 1

房型 ID

回應欄位 · data

id
string
description
string | null
status
string
name
string
bedConfig
unknown
propertyId
string
facilities
unknown
createdAt
Date
updatedAt
Date
inventoryUnit
string
unitsTotal
number
capacityPerUnit
number
basePriceTwd
number
floorSizeSqm
number | null
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/room-types/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "description": "…",
    "status": "…",
    "name": "…",
    "bedConfig": "…",
    "propertyId": "…",
    "facilities": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z",
    "inventoryUnit": "…",
    "unitsTotal": 0,
    "capacityPerUnit": 0,
    "basePriceTwd": 0,
    "floorSizeSqm": 0
  }
}

update a room type

PATCH/api/v1/lodging/room-types/{id}
lodging.manage模組:lodging

參數

id路徑
string· min 1

房型 ID

name選填
string· max 200 · min 1

房型名稱(如標準雙人房)

inventoryUnit選填
enum
roombed

庫存單位:room 以房計/bed 以床位計

unitsTotal選填
integer· max 10000 · min 1

此房型可售總單元數(房數或床位數)

capacityPerUnit選填
integer· max 100 · min 1

每單元可容納人數

basePriceTwd選填
integer· max 10000000 · min 0

每晚每單元基準售價(新台幣)

description選填
string· max 2000

房型介紹文字

floorSizeSqm選填
integer

房間坪數(平方公尺)

bedType選填
string

床型代碼(須為合法 bed type,搭配 bedCount 才生效)

bedCount選填
integer

該床型數量(須大於 0 才生效)

facilities選填
array

房型設施代碼陣列(須為合法 amenity key;送空陣列代表清空)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/lodging/room-types/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

archive

POST/api/v1/lodging/room-types/{id}/archive
lodging.manage模組:lodging

參數

id路徑
string· min 1

房型 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/archive \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

per-night availability +

GET/api/v1/lodging/room-types/{id}/availability
lodging.read

參數

id路徑
string· min 1

房型 ID

checkIn必填
string· min 1

入住日(YYYY-MM-DD,含此晚)

checkOut必填
string· min 1

退房日(YYYY-MM-DD,不含此晚)

回應欄位 · data

available
number
nights
number
totalPriceTwd
number
perNight
object[]
night
string
capacity
number
booked
number
remaining
number
priceTwd
number
status
string
請求
curl -X GET "https://your-tenant.example.com/api/v1/lodging/room-types/<id>/availability?checkIn=<checkIn>&checkOut=<checkOut>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "available": 0,
    "nights": 0,
    "totalPriceTwd": 0,
    "perNight": [
      {
        "night": "…",
        "capacity": 0,
        "booked": 0,
        "remaining": 0,
        "priceTwd": 0,
        "status": "…"
      }
    ]
  }
}

per-night

GET/api/v1/lodging/room-types/{id}/availability/breakdown
lodging.read

參數

id路徑
string· min 1

房型 ID

from必填
string· min 1

起始日(YYYY-MM-DD,含此晚)

to必填
string· min 1

結束日(YYYY-MM-DD,不含此晚)

回應欄位 · data[]

night
string
directBooked
number
packageBooked
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/lodging/room-types/<id>/availability/breakdown?from=<from>&to=<to>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "night": "…",
      "directBooked": 0,
      "packageBooked": 0
    }
  ]
}

room-type gallery images.

GET/api/v1/lodging/room-types/{id}/images
lodging.read模組:lodging

參數

id路徑
string· min 1

房型 ID

回應欄位 · data[]

id
string
url
string
caption
string | null
displayOrder
number
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/room-types/<id>/images \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "url": "…",
      "caption": "…",
      "displayOrder": 0
    }
  ]
}

add a room-type gallery image

POST/api/v1/lodging/room-types/{id}/images
lodging.manage模組:lodging

參數

id路徑
string· min 1

房型 ID

url必填
string· min 1

圖片網址

caption選填
string

圖片說明文字(可省略)

displayOrder選填
integer

在相簿中的排序序號,數字越小越前面,預設 0

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/images \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "<url>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

batch-override the

POST/api/v1/lodging/room-types/{id}/nights/override
lodging.manage模組:lodging

參數

id路徑
string· min 1

房型 ID

from必填
string

套用起始日(YYYY-MM-DD,含此日)

to必填
string

套用結束日(YYYY-MM-DD,含此日;須不早於起始日)

priceTwd選填
integer· max 10000000 · min 0

覆寫的每晚售價(新台幣),省略則不調整價格

capacity選填
integer· max 10000 · min 1

覆寫的每晚可售單元數,若低於已訂數量會回 409 衝突

status選填
enum
openclosed

每晚開關房狀態:open 開放/closed 封房

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/lodging/room-types/<id>/nights/override \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "<from>",
    "to": "<to>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

旅宿 dashboard overview

GET/api/v1/lodging/stats
lodging.read

回應欄位 · data

tonightCheckInUnits
number
tonightCheckInGuests
number
weekOccupancyPct
number
next7AvailableUnits
number
pendingPaymentCount
number
pendingPaymentTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/lodging/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "tonightCheckInUnits": 0,
    "tonightCheckInGuests": 0,
    "weekOccupancyPct": 0,
    "next7AvailableUnits": 0,
    "pendingPaymentCount": 0,
    "pendingPaymentTwd": 0
  }
}

/members

list/search the tenant customer

GET/api/v1/members
member.read

參數

q選填
string

關鍵字,模糊比對會員姓名、Email 或電話

county選填
string

縣市篩選,僅回傳通訊地址在該縣市的會員

year選填
string· 格式限定

加入年份(西元四位數),僅回傳該年註冊的會員

page選填
integer

分頁頁碼,從 1 起算,預設第 1 頁

pageSize選填
integer· max 200

每頁筆數,上限 200,預設由後端決定

回應欄位 · data

rows
object[]
userId
string
email
string
name
string
createdAt
Date
phone
string | null
address
string | null
birthDate
string | null
orderCount
number
paidOrderCount
number
totalSpent
number
lastOrderAt
Date | null
pdpaSignedAt
Date | null
anonymizedAt
Date | null
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/members \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "userId": "…",
        "email": "…",
        "name": "…",
        "createdAt": "2026-06-30T08:00:00.000Z",
        "phone": "…",
        "address": "…",
        "birthDate": "…",
        "orderCount": 0,
        "paidOrderCount": 0,
        "totalSpent": 0,
        "lastOrderAt": null,
        "pdpaSignedAt": null,
        "anonymizedAt": null
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}

full member detail

GET/api/v1/members/{id}
member.read

參數

id路徑
string· min 1

會員(顧客)的使用者 ID

回應欄位 · data

profile
object
userId
string
email
string
name
string
createdAt
Date
phone
string | null
address
string | null
birthDate
string | null
orderCount
number
paidOrderCount
number
totalSpent
number
lastOrderAt
Date | null
pdpaSignedAt
Date | null
anonymizedAt
Date | null
orders
object[]
id
string
orderNumber
string
status
string
total
number
createdAt
Date
tripTitle
string
consents
object[]
id
string
kind
string
version
number
signedAt
Date
ipAddress
string | null
請求
curl -X GET https://your-tenant.example.com/api/v1/members/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "profile": {
      "userId": "…",
      "email": "…",
      "name": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "phone": "…",
      "address": "…",
      "birthDate": "…",
      "orderCount": 0,
      "paidOrderCount": 0,
      "totalSpent": 0,
      "lastOrderAt": null,
      "pdpaSignedAt": null,
      "anonymizedAt": null
    },
    "orders": [
      {
        "id": "…",
        "orderNumber": "…",
        "status": "…",
        "total": 0,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "tripTitle": "…"
      }
    ],
    "consents": [
      {
        "id": "…",
        "kind": "…",
        "version": 0,
        "signedAt": "2026-06-30T08:00:00.000Z",
        "ipAddress": "…"
      }
    ]
  }
}

irreversible PDPA anonymization of one

POST/api/v1/members/{id}/anonymize
member.update

參數

id路徑
string· min 1

欲匿名化的會員(顧客)使用者 ID

reason選填
string

匿名化原因,記入稽核紀錄備查

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/members/<id>/anonymize \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

given a batch of member

GET/api/v1/members/expiry-warnings
member.read

參數

ids必填
string

以逗號分隔的會員使用者 ID 批次,上限 200 個,回傳其中護照即將到期者

回應欄位 · data

userIds
string[]
請求
curl -X GET "https://your-tenant.example.com/api/v1/members/expiry-warnings?ids=<ids>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "userIds": [
      "…"
    ]
  }
}

member directory KPI cards

GET/api/v1/members/stats
member.read

回應欄位 · data

totalMembers
number
newThisMonth
number
withOrders
number
averageOrders
number
請求
curl -X GET https://your-tenant.example.com/api/v1/members/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "totalMembers": 0,
    "newThisMonth": 0,
    "withOrders": 0,
    "averageOrders": 0
  }
}

/message-templates

list canned message templates

GET/api/v1/message-templates
message_template.read

參數

channel選填
enum
lineemail

依發送管道篩選範本(line 或 email)

回應欄位 · data[]

id
string
key
string | null
stage
"受理" | "審核不通過" | "未成團通知" | "中籤通知" | "行前說明" | "收尾款" | "訂餐調查" | "裝備調查" | "出團完成"
channel
"email" | "line"
title
string
bodySingle
string
bodyMulti
string | null
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/message-templates \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "key": "…",
      "stage": "受理",
      "channel": "email",
      "title": "…",
      "bodySingle": "…",
      "bodyMulti": "…",
      "isActive": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/message-templates
message_template.manage

參數

key選填
string

範本識別碼,2–64 碼大寫英數 / _ / -(用於程式化引用,選填,自動轉大寫)

stage必填
enum

訊息對應的 SOP 階段

channel必填
enum

發送管道(line 或 email)

title必填
string· max 200 · min 1

範本標題(供後台辨識)

bodySingle必填
string· max 5000 · min 1

單人版訊息內文

bodyMulti選填
string· max 5000

多人版訊息內文(留空表示沿用單人版;選填)

isActive選填
boolean

是否啟用(停用後不出現在可選範本中)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/message-templates \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stage": "<stage>",
    "channel": "<channel>",
    "title": "<title>",
    "bodySingle": "<bodySingle>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

single canned message template detail.

GET/api/v1/message-templates/{id}
message_template.read

參數

id路徑
string· min 1

訊息範本 ID

回應欄位 · data

id
string
key
string | null
stage
"受理" | "審核不通過" | "未成團通知" | "中籤通知" | "行前說明" | "收尾款" | "訂餐調查" | "裝備調查" | "出團完成"
channel
"email" | "line"
title
string
bodySingle
string
bodyMulti
string | null
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/message-templates/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "key": "…",
    "stage": "受理",
    "channel": "email",
    "title": "…",
    "bodySingle": "…",
    "bodyMulti": "…",
    "isActive": true,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
PATCH/api/v1/message-templates/{id}
message_template.manage

參數

id路徑
string· min 1

要更新的訊息範本 ID

key選填
string

範本識別碼,2–64 碼大寫英數 / _ / -(用於程式化引用,選填,自動轉大寫)

stage必填
enum

訊息對應的 SOP 階段

channel必填
enum

發送管道(line 或 email)

title必填
string· max 200 · min 1

範本標題(供後台辨識)

bodySingle必填
string· max 5000 · min 1

單人版訊息內文

bodyMulti選填
string· max 5000

多人版訊息內文(留空表示沿用單人版;選填)

isActive選填
boolean

是否啟用(停用後不出現在可選範本中)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/message-templates/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stage": "<stage>",
    "channel": "<channel>",
    "title": "<title>",
    "bodySingle": "<bodySingle>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/message-templates/{id}
message_template.manage

參數

id路徑
string· min 1

訊息範本 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/message-templates/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

enable / disable

POST/api/v1/message-templates/{id}/active
message_template.manage

參數

id路徑
string· min 1

要啟用 / 停用的訊息範本 ID

isActive必填
boolean

true 啟用、false 停用(軟刪除)此範本

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/message-templates/<id>/active \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/orders

list/search/filter orders

GET/api/v1/orders
order.read

參數

status選填
string

依訂單顯示狀態篩選(如 pending、paid、cancelled)

assignment選填
string

依派發狀態篩選(如 unassigned、assigned)

rooming選填
string

依分房狀態篩選

dateFrom選填
string

出發日期區間起(格式 YYYY-MM-DD,含當日)

dateTo選填
string

出發日期區間迄(格式 YYYY-MM-DD,含當日)

q選填
string

關鍵字搜尋(訂單編號、訂購人姓名或 Email 等)

agencyId選填
string

依合作旅行社 ID 篩選(同業單)

page選填
integer

頁碼,從 1 起算,預設第 1 頁

pageSize選填
integer· max 200

每頁筆數,上限 200

回應欄位 · data

rows
object[]
id
string
orderNumber
string
bookingState
string
paymentState
string
refundState
string
grossReceivableTwd
number
collectedTwd
number
customerCashAppliedTwd
number
outstandingTwd
number
partySize
number
createdAt
Date
notes
string | null
userId
string
userName
string
userEmail
string
primaryTravelerName
string | null
primaryTravelerPhone
string | null
tripId
string
tripTitle
string
tripSlug
string
departureId
string
departureDate
string
returnDate
string
assignedToUserId
string | null
assigneeName
string | null
assignmentStatus
string
assignedAt
Date | null
assignedByUserId
string | null
createdByUserId
string | null
pendingConsent
boolean
roomingStatus
RoomingStatus
lotteryState
string | null
failoverFromOrderId
string | null
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/orders \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "orderNumber": "…",
        "bookingState": "…",
        "paymentState": "…",
        "refundState": "…",
        "grossReceivableTwd": 0,
        "collectedTwd": 0,
        "customerCashAppliedTwd": 0,
        "outstandingTwd": 0,
        "partySize": 0,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "notes": "…",
        "userId": "…",
        "userName": "…",
        "userEmail": "…",
        "primaryTravelerName": "…",
        "primaryTravelerPhone": "…",
        "tripId": "…",
        "tripTitle": "…",
        "tripSlug": "…",
        "departureId": "…",
        "departureDate": "…",
        "returnDate": "…",
        "assignedToUserId": "…",
        "assigneeName": "…",
        "assignmentStatus": "…",
        "assignedAt": null,
        "assignedByUserId": "…",
        "createdByUserId": "…",
        "pendingConsent": true,
        "roomingStatus": "…",
        "lotteryState": "…",
        "failoverFromOrderId": "…"
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}
POST/api/v1/orders
order.create

參數

tripId必填
string· min 1

行程 ID

departureId必填
string· min 1

梯次 ID,決定佔位的出發團

primaryEmail必填
string· min 1

訂購人 Email,須對應已註冊會員

partySize必填
integer

報名人數,決定佔位數,須為 1 至 20 之間整數

travelers必填
array

旅客名單,筆數須與報名人數一致

paymentMethod必填
enum
cashatmmanual

收款方式:cash 現金、atm 轉帳、manual 人工

customerType選填
enum
directagency

客戶類型:direct 直客、agency 同業,預設直客

paymentPlan選填
enum
fulldeposit

付款方案:full 全額、deposit 訂金,預設全額

receivingAccountId選填
string

收款帳戶 ID,指定本筆款項入帳的帳戶

notes選填
string

訂單備註

回應欄位 · data

orderId
string
orderNumber
string
請求
curl -X POST https://your-tenant.example.com/api/v1/orders \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tripId": "<tripId>",
    "departureId": "<departureId>",
    "primaryEmail": "<primaryEmail>",
    "partySize": 0,
    "travelers": [],
    "paymentMethod": "cash"
  }'
回應
{
  "ok": true,
  "data": {
    "orderId": "…",
    "orderNumber": "…"
  }
}

full kind-aware order detail

GET/api/v1/orders/{id}
order.read

參數

id路徑
string· min 1

訂單 ID

回應欄位 · data

id
string
orderNumber
string
bookingState
string
paymentState
string
refundState
string
grossReceivableTwd
number
collectedTwd
number
customerCashAppliedTwd
number
outstandingTwd
number
partySize
number
createdAt
Date
notes
string | null
userId
string
userName
string
userEmail
string
primaryTravelerName
string | null
primaryTravelerPhone
string | null
tripId
string
tripTitle
string
tripSlug
string
departureId
string
departureDate
string
returnDate
string
assignedToUserId
string | null
assigneeName
string | null
assignmentStatus
string
assignedAt
Date | null
assignedByUserId
string | null
createdByUserId
string | null
pendingConsent
boolean
roomingStatus
RoomingStatus
lotteryState
string | null
failoverFromOrderId
string | null
kind
"lodging" | "tour"
lodging
AdminLodgingHeader | null
travelers
object[]
id
string
fullName
string
idNumberMask
string | null
passportNoMask
string | null
birthDate
string | null
phone
string | null
email
string | null
emergencyContactName
string | null
emergencyContactPhone
string | null
isPrimary
boolean
gender
string | null
roomPreference
string | null
roommatePref
string | null
address
string | null
roomLabel
string | null
chargeLines
object[]
id
string
type
string
amountTwd
number
description
string
sourceType
string
reversesChargeLineId
string | null
createdAt
Date
transactions
object[]
id
string
direction
string
type
string
amountTwd
number
feeTwd
number
netTwd
number
provider
string
providerTradeNo
string | null
refundId
string | null
occurredAt
Date
schedules
object[]
id
string
purpose
string
targetAmountTwd
number
status
string
dueAt
Date | null
sequence
number
intents
object[]
id
string
purpose
string
amountTwd
number
status
string
scheduleId
string | null
attemptProvider
string | null
attemptMethod
string | null
attemptStatus
string | null
bankCode
string | null
virtualAccount
string | null
payExpireAt
Date | null
請求
curl -X GET https://your-tenant.example.com/api/v1/orders/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "orderNumber": "…",
    "bookingState": "…",
    "paymentState": "…",
    "refundState": "…",
    "grossReceivableTwd": 0,
    "collectedTwd": 0,
    "customerCashAppliedTwd": 0,
    "outstandingTwd": 0,
    "partySize": 0,
    "createdAt": "2026-06-30T08:00:00.000Z",
    "notes": "…",
    "userId": "…",
    "userName": "…",
    "userEmail": "…",
    "primaryTravelerName": "…",
    "primaryTravelerPhone": "…",
    "tripId": "…",
    "tripTitle": "…",
    "tripSlug": "…",
    "departureId": "…",
    "departureDate": "…",
    "returnDate": "…",
    "assignedToUserId": "…",
    "assigneeName": "…",
    "assignmentStatus": "…",
    "assignedAt": null,
    "assignedByUserId": "…",
    "createdByUserId": "…",
    "pendingConsent": true,
    "roomingStatus": "…",
    "lotteryState": "…",
    "failoverFromOrderId": "…",
    "kind": "lodging",
    "lodging": null,
    "travelers": [
      {
        "id": "…",
        "fullName": "…",
        "idNumberMask": "…",
        "passportNoMask": "…",
        "birthDate": "…",
        "phone": "…",
        "email": "…",
        "emergencyContactName": "…",
        "emergencyContactPhone": "…",
        "isPrimary": true,
        "gender": "…",
        "roomPreference": "…",
        "roommatePref": "…",
        "address": "…",
        "roomLabel": "…"
      }
    ],
    "chargeLines": [
      {
        "id": "…",
        "type": "…",
        "amountTwd": 0,
        "description": "…",
        "sourceType": "…",
        "reversesChargeLineId": "…",
        "createdAt": "2026-06-30T08:00:00.000Z"
      }
    ],
    "transactions": [
      {
        "id": "…",
        "direction": "…",
        "type": "…",
        "amountTwd": 0,
        "feeTwd": 0,
        "netTwd": 0,
        "provider": "…",
        "providerTradeNo": "…",
        "refundId": "…",
        "occurredAt": "2026-06-30T08:00:00.000Z"
      }
    ],
    "schedules": [
      {
        "id": "…",
        "purpose": "…",
        "targetAmountTwd": 0,
        "status": "…",
        "dueAt": null,
        "sequence": 0
      }
    ],
    "intents": [
      {
        "id": "…",
        "purpose": "…",
        "amountTwd": 0,
        "status": "…",
        "scheduleId": "…",
        "attemptProvider": "…",
        "attemptMethod": "…",
        "attemptStatus": "…",
        "bankCode": "…",
        "virtualAccount": "…",
        "payExpireAt": null
      }
    ]
  }
}

manual charge adjustment

POST/api/v1/orders/{id}/adjust
order.adjust

參數

id路徑
string· min 1

訂單 ID

kind必填
enum
surchargeallowance

調整類型:surcharge 加收、allowance 減免

amountTwd必填
integer

調整金額(新台幣,正整數)

description必填
string· min 1

調整事由說明

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/adjust \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "surcharge",
    "amountTwd": 0,
    "description": "<description>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

首次派發訂單給承辦業務

POST/api/v1/orders/{id}/assign
order.assign

參數

id路徑
string· min 1

訂單 ID

assigneeUserId必填
string· min 1

受派業務的使用者 ID

reason選填
string· max 500

派發事由說明(上限 500 字)

回應欄位 · data

ok
boolean
idempotent
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/assign \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "assigneeUserId": "<assigneeUserId>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "idempotent": true
  }
}

產生/重用尾款

POST/api/v1/orders/{id}/balance-link
order.update

參數

id路徑
string· min 1

訂單 ID

回應欄位 · data

ok
boolean
amountTwd
number
scheduleId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/balance-link \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "amountTwd": 0,
    "scheduleId": "…"
  }
}

cancel a tour order

POST/api/v1/orders/{id}/cancel
order.update

參數

id路徑
string· min 1

訂單 ID

reason選填
string

取消事由說明

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/cancel \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

線控手動抽籤裁決:won

POST/api/v1/orders/{id}/lottery/resolve
lottery.manage

參數

id路徑
string· min 1

訂單 ID

outcome必填
enum
wonlost

抽籤裁決結果:won 中籤確認、lost 未中籤(啟動備案或取消)

回應欄位 · data

ok
boolean
outcome
"won" | "lost"
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/lottery/resolve \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "outcome": "won"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "outcome": "won"
  }
}

mark an order paid by manual

POST/api/v1/orders/{id}/mark-paid
payment.update

參數

id路徑
string· min 1

訂單 ID

note選填
string

對帳備註,記錄人工核款說明

receivingAccountId選填
string

收款帳戶 ID,指定本筆款項入帳的帳戶

回應欄位 · data

idempotent
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/mark-paid \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "idempotent": true
  }
}

重新指派已派發訂單

POST/api/v1/orders/{id}/reassign
order.reassign

參數

id路徑
string· min 1

訂單 ID

assigneeUserId必填
string· min 1

重新指派的承接業務使用者 ID

reason選填
string· max 500

重派事由說明(上限 500 字)

回應欄位 · data

ok
boolean
idempotent
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/reassign \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "assigneeUserId": "<assigneeUserId>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "idempotent": true
  }
}

create + submit a customer refund

POST/api/v1/orders/{id}/refunds
refund.create

參數

id路徑
string· min 1

訂單 ID

refundKind必填
enum
receivable_reductionoverpayment_return

退款種類:receivable_reduction 應收減免、overpayment_return 溢收退還

reason必填
string· min 1

退款事由說明

amountTwd必填
integer

退款總金額(新台幣,正整數)

executionMethod選填
enum
chargebackremit

退款執行方式:chargeback 原路退刷、remit 銀行匯款

originAccountId選填
string

出款來源帳戶 ID(匯款退款時指定)

adminFeeTwd選填
integer

手續費/行政費(新台幣,非負整數)

remitFeeTwd選填
integer

匯款轉帳費(新台幣,非負整數)

payeeAccountName選填
string

受款人戶名(匯款退款時填寫)

payeeBankCode選填
string

受款銀行代碼(匯款退款時填寫)

payeeAccountNumber選填
string

受款銀行帳號(匯款退款時填寫)

lines選填
array

退款明細列;省略時依退款總額處理

回應欄位 · data

id
string
refundNumber
string
status
RefundStatus
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/refunds \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "refundKind": "receivable_reduction",
    "reason": "<reason>",
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "refundNumber": "…",
    "status": "…"
  }
}

approve a submitted

POST/api/v1/orders/{id}/refunds/{refundId}/approve
refund.approve

參數

refundId路徑
string· min 1

退款單 ID

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/{id}/refunds/<refundId>/approve \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

mark an approved

POST/api/v1/orders/{id}/refunds/{refundId}/mark-paid
refund.mark_paid

參數

refundId路徑
string· min 1

退款單 ID

bankReference選填
string

出款的銀行交易參考號(匯款憑證)

receivingAccountId選填
string

出款帳戶 ID;remit 退款須指定具匯款能力的帳戶

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/{id}/refunds/<refundId>/mark-paid \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

reject a submitted

POST/api/v1/orders/{id}/refunds/{refundId}/reject
refund.reject

參數

refundId路徑
string· min 1

退款單 ID

reason選填
string

退件事由說明

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/{id}/refunds/<refundId>/reject \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

reverse an existing charge line

POST/api/v1/orders/{id}/reverse
order.adjust

參數

id路徑
string· min 1

訂單 ID

chargeLineId必填
string· min 1

欲沖正的應收項目(charge line)ID

description必填
string· min 1

沖正事由說明

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/reverse \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "chargeLineId": "<chargeLineId>",
    "description": "<description>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

人工核可/駁回登山資格審核

POST/api/v1/orders/{id}/review-screening
screening.review

參數

id路徑
string· min 1

訂單 ID

decision必填
enum
approvereject

登山資格審核裁決:approve 核可、reject 駁回

note選填
string· max 500

審核註記說明(上限 500 字)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/review-screening \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "approve"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

新增旅客到訂單

POST/api/v1/orders/{id}/travelers
order.update

參數

fullName選填
string· min 1

旅客全名,須與證件一致;新增旅客時必填,更新時可省略

phone選填
string

旅客聯絡電話

email選填
string

旅客電子郵件

birthDate選填
string

旅客出生日期(格式 YYYY-MM-DD)

emergencyContactName選填
string

緊急聯絡人姓名

emergencyContactPhone選填
string

緊急聯絡人電話

gender選填
enum
malefemaleother

旅客性別:male 男、female 女、other 其他

roomPreference選填
string

房型偏好(用於分房作業)

roommatePref選填
string

指定同住室友(用於分房作業)

address選填
string

旅客通訊地址

idNumber選填
string

身分證字號,屬個資將加密保存

passportNo選填
string

護照號碼,屬個資將加密保存

id路徑
string· min 1

訂單 ID

回應欄位 · data

ok
boolean
travelerId
string
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/travelers \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "travelerId": "…"
  }
}

更新旅客資料

PATCH/api/v1/orders/{id}/travelers/{travelerId}
order.update

參數

fullName選填
string· min 1

旅客全名,須與證件一致;新增旅客時必填,更新時可省略

phone選填
string

旅客聯絡電話

email選填
string

旅客電子郵件

birthDate選填
string

旅客出生日期(格式 YYYY-MM-DD)

emergencyContactName選填
string

緊急聯絡人姓名

emergencyContactPhone選填
string

緊急聯絡人電話

gender選填
enum
malefemaleother

旅客性別:male 男、female 女、other 其他

roomPreference選填
string

房型偏好(用於分房作業)

roommatePref選填
string

指定同住室友(用於分房作業)

address選填
string

旅客通訊地址

idNumber選填
string

身分證字號,屬個資將加密保存

passportNo選填
string

護照號碼,屬個資將加密保存

id路徑
string· min 1

訂單 ID

travelerId路徑
string· min 1

旅客 ID

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

移除旅客

DELETE/api/v1/orders/{id}/travelers/{travelerId}
order.update

參數

id路徑
string· min 1

訂單 ID

travelerId路徑
string· min 1

旅客 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

顯示旅客證號/護照全碼

POST/api/v1/orders/{id}/travelers/{travelerId}/reveal
order.read

參數

id路徑
string· min 1

訂單 ID

travelerId路徑
string· min 1

旅客 ID

field必填
enum
idNumberpassportNo

欲顯示全碼的個資欄位:idNumber 身分證字號、passportNo 護照號碼

回應欄位 · data

field
"idNumber" | "passportNo"
value
string | null
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId>/reveal \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "field": "idNumber"
  }'
回應
{
  "ok": true,
  "data": {
    "field": "idNumber",
    "value": "…"
  }
}

更新旅客分房需求

PATCH/api/v1/orders/{id}/travelers/{travelerId}/rooming
order.update

參數

roomPreference選填
string

房型偏好(用於分房作業)

roommatePref選填
string

指定同住室友(用於分房作業)

id路徑
string· min 1

訂單 ID

travelerId路徑
string· min 1

旅客 ID

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/orders/<id>/travelers/<travelerId>/rooming \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

批次把多張訂單派給同一位業務

POST/api/v1/orders/bulk-assign
order.assign

參數

orderIds必填
array· max 100 · min 1

欲批次派發的訂單 ID 陣列(1 至 100 筆)

assigneeUserId必填
string· min 1

受派業務的使用者 ID(所有訂單派給同一人)

reason選填
string· max 500

派發事由說明(上限 500 字)

回應欄位 · data

ok
boolean
assignedCount
number
skippedCount
number
請求
curl -X POST https://your-tenant.example.com/api/v1/orders/bulk-assign \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "orderIds": [],
    "assigneeUserId": "<assigneeUserId>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "assignedCount": 0,
    "skippedCount": 0
  }
}

匯出訂單

GET/api/v1/orders/export
order.read

參數

status選填
string

依訂單顯示狀態篩選(如 pending、paid、cancelled)

assignment選填
string

依派發狀態篩選(如 unassigned、assigned)

rooming選填
string

依分房狀態篩選

dateFrom選填
string

出發日期區間起(格式 YYYY-MM-DD,含當日)

dateTo選填
string

出發日期區間迄(格式 YYYY-MM-DD,含當日)

q選填
string

關鍵字搜尋(訂單編號、訂購人姓名或 Email 等)

agencyId選填
string

依合作旅行社 ID 篩選(同業單)

回應欄位 · data

rows
object[]
id
string
orderNumber
string
bookingState
string
paymentState
string
refundState
string
grossReceivableTwd
number
collectedTwd
number
customerCashAppliedTwd
number
outstandingTwd
number
partySize
number
createdAt
Date
notes
string | null
userId
string
userName
string
userEmail
string
primaryTravelerName
string | null
primaryTravelerPhone
string | null
tripId
string
tripTitle
string
tripSlug
string
departureId
string
departureDate
string
returnDate
string
assignedToUserId
string | null
assigneeName
string | null
assignmentStatus
string
assignedAt
Date | null
assignedByUserId
string | null
createdByUserId
string | null
pendingConsent
boolean
roomingStatus
RoomingStatus
lotteryState
string | null
failoverFromOrderId
string | null
total
number
truncated
boolean
請求
curl -X GET https://your-tenant.example.com/api/v1/orders/export \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "orderNumber": "…",
        "bookingState": "…",
        "paymentState": "…",
        "refundState": "…",
        "grossReceivableTwd": 0,
        "collectedTwd": 0,
        "customerCashAppliedTwd": 0,
        "outstandingTwd": 0,
        "partySize": 0,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "notes": "…",
        "userId": "…",
        "userName": "…",
        "userEmail": "…",
        "primaryTravelerName": "…",
        "primaryTravelerPhone": "…",
        "tripId": "…",
        "tripTitle": "…",
        "tripSlug": "…",
        "departureId": "…",
        "departureDate": "…",
        "returnDate": "…",
        "assignedToUserId": "…",
        "assigneeName": "…",
        "assignmentStatus": "…",
        "assignedAt": null,
        "assignedByUserId": "…",
        "createdByUserId": "…",
        "pendingConsent": true,
        "roomingStatus": "…",
        "lotteryState": "…",
        "failoverFromOrderId": "…"
      }
    ],
    "total": 0,
    "truncated": true
  }
}

order KPI counts

GET/api/v1/orders/stats
order.read

回應欄位 · data

pendingPayment
number
depositPaid
number
paid
number
cancelled
number
refunded
number
completed
number
thisMonthPaidTwd
number
請求
curl -X GET https://your-tenant.example.com/api/v1/orders/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "pendingPayment": 0,
    "depositPaid": 0,
    "paid": 0,
    "cancelled": 0,
    "refunded": 0,
    "completed": 0,
    "thisMonthPaidTwd": 0
  }
}

/payment-requests

list/search/filter 對外應付

GET/api/v1/payment-requests
payable.read

參數

status選填
enum
draftsubmittedapprovedpaidrejectedcancelledall

依狀態篩選(draft 草稿 / submitted 已送審 / approved 已核准 / paid 已付款 / rejected 已退件 / cancelled 已取消 / all 全部)

payeeType選填
enum
supplierguidestaff_commissionotherall

依收款對象類型篩選(supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他 / all 全部)

departureId選填
string

依關聯梯次 id 篩選

createdByUserId選填
string

依建單人 user id 篩選

q選填
string

關鍵字搜尋(請款單號、收款對象名稱等)

page選填
integer

頁碼(從 1 起算)

pageSize選填
integer· max 200

每頁筆數(上限 200)

回應欄位 · data

rows
object[]
id
string
requestNumber
string
status
PaymentRequestStatus
payeeType
PayeeType
payeeName
string
amountTwd
number
netAmountTwd
number
taxAmountTwd
number
departureId
string | null
departureLabel
string | null
description
string
createdAt
Date
updatedAt
Date
createdByUserId
string
createdByName
string | null
paidAt
Date | null
submittedAt
Date | null
approvedAt
Date | null
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/payment-requests \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "requestNumber": "…",
        "status": "…",
        "payeeType": "…",
        "payeeName": "…",
        "amountTwd": 0,
        "netAmountTwd": 0,
        "taxAmountTwd": 0,
        "departureId": "…",
        "departureLabel": "…",
        "description": "…",
        "createdAt": "2026-06-30T08:00:00.000Z",
        "updatedAt": "2026-06-30T08:00:00.000Z",
        "createdByUserId": "…",
        "createdByName": "…",
        "paidAt": null,
        "submittedAt": null,
        "approvedAt": null
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}
POST/api/v1/payment-requests
payable.create

參數

payeeType必填
enum
supplierguidestaff_commissionother

收款對象類型(supplier 供應商 / guide 領隊嚮導 / staff_commission 員工獎金 / other 其他)

payeeName必填
string· min 1

收款對象名稱

payeeBankAccount選填
string

收款銀行帳號

payeeBankName選填
string

收款銀行名稱

payeeBankBranch選填
string

收款銀行分行

payeeTaxId選填
string

收款對象統一編號 / 稅籍編號

departureId選填
string

關聯梯次 id(將此請款歸屬至特定出團)

description必填
string· min 1

請款單摘要說明

taxAmountTwd選填
integer

稅額(TWD),未填視為 0

items必填
array· min 1

請款細項陣列(至少一筆)

submitImmediately選填
boolean

是否建立後立即送審(true 則同交易送出,跳過草稿)

回應欄位 · data

id
string
requestNumber
string
status
PaymentRequestStatus
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "payeeType": "supplier",
    "payeeName": "<payeeName>",
    "description": "<description>",
    "items": []
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "requestNumber": "…",
    "status": "…"
  }
}

單一對外應付請款單完整明細

GET/api/v1/payment-requests/{id}
payable.read

參數

id路徑
string· min 1

請款單 id(路徑參數)

回應欄位 · data

payeeBankAccount
string | null
payeeBankName
string | null
payeeBankBranch
string | null
payeeTaxId
string | null
submittedByUserId
string | null
submittedByName
string | null
approvedByUserId
string | null
approvedByName
string | null
paidByUserId
string | null
paidByName
string | null
rejectedAt
Date | null
rejectedByName
string | null
rejectionReason
string | null
cancelledAt
Date | null
cancelledByName
string | null
cancellationReason
string | null
pdfGeneratedAt
Date | null
paperPrintedAt
Date | null
paperSignedBy
string | null
bankReference
string | null
items
object[]
id
string
category
string
description
string
quantity
number
unitPriceTwd
number
totalTwd
number
notes
string | null
sortOrder
number
audit
object[]
id
string
action
string
createdAt
Date
actorUserId
string | null
actorName
string | null
metadata
unknown
ipAddress
string | null
id
string
requestNumber
string
status
PaymentRequestStatus
payeeType
PayeeType
payeeName
string
amountTwd
number
netAmountTwd
number
taxAmountTwd
number
departureId
string | null
departureLabel
string | null
description
string
createdAt
Date
updatedAt
Date
createdByUserId
string
createdByName
string | null
paidAt
Date | null
submittedAt
Date | null
approvedAt
Date | null
請求
curl -X GET https://your-tenant.example.com/api/v1/payment-requests/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "payeeBankAccount": "…",
    "payeeBankName": "…",
    "payeeBankBranch": "…",
    "payeeTaxId": "…",
    "submittedByUserId": "…",
    "submittedByName": "…",
    "approvedByUserId": "…",
    "approvedByName": "…",
    "paidByUserId": "…",
    "paidByName": "…",
    "rejectedAt": null,
    "rejectedByName": "…",
    "rejectionReason": "…",
    "cancelledAt": null,
    "cancelledByName": "…",
    "cancellationReason": "…",
    "pdfGeneratedAt": null,
    "paperPrintedAt": null,
    "paperSignedBy": "…",
    "bankReference": "…",
    "items": [
      {
        "id": "…",
        "category": "…",
        "description": "…",
        "quantity": 0,
        "unitPriceTwd": 0,
        "totalTwd": 0,
        "notes": "…",
        "sortOrder": 0
      }
    ],
    "audit": [
      {
        "id": "…",
        "action": "…",
        "createdAt": "2026-06-30T08:00:00.000Z",
        "actorUserId": "…",
        "actorName": "…",
        "metadata": "…",
        "ipAddress": "…"
      }
    ],
    "id": "…",
    "requestNumber": "…",
    "status": "…",
    "payeeType": "…",
    "payeeName": "…",
    "amountTwd": 0,
    "netAmountTwd": 0,
    "taxAmountTwd": 0,
    "departureId": "…",
    "departureLabel": "…",
    "description": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z",
    "createdByUserId": "…",
    "createdByName": "…",
    "paidAt": null,
    "submittedAt": null,
    "approvedAt": null
  }
}

核可請款單

POST/api/v1/payment-requests/{id}/approve
payable.approve

參數

id路徑
string· min 1

請款單 id(路徑參數)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/approve \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

取消請款單

POST/api/v1/payment-requests/{id}/cancel
payable.create

參數

id路徑
string· min 1

請款單 id(路徑參數)

reason選填
string

取消原因;留空預設為「使用者取消」(上限 200 字)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/cancel \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

標記請款單已付

POST/api/v1/payment-requests/{id}/mark-paid
payable.mark_paid

參數

id路徑
string· min 1

請款單 id(路徑參數)

bankReference必填
string· min 1

網銀交易序號 / 轉帳憑證號(必填)

paperSignedBy選填
string

紙本簽核人姓名

receivingAccountId選填
string

出款帳戶 id(從哪個收款帳戶付出)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-paid \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bankReference": "<bankReference>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

標記 PDF/紙本已產生

POST/api/v1/payment-requests/{id}/mark-printed
payable.print

參數

id路徑
string· min 1

請款單 id(路徑參數)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-printed \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

記錄紙本簽核人

POST/api/v1/payment-requests/{id}/mark-signed
payable.create

參數

id路徑
string· min 1

請款單 id(路徑參數)

signedBy必填
string· min 1

紙本簽核人姓名(必填)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/mark-signed \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "signedBy": "<signedBy>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

退件請款單

POST/api/v1/payment-requests/{id}/reject
payable.approve

參數

id路徑
string· min 1

請款單 id(路徑參數)

reason必填
string· min 1

退件原因(必填,回饋給建單人)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/reject \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "<reason>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

送審請款單

POST/api/v1/payment-requests/{id}/submit
payable.create

參數

id路徑
string· min 1

請款單 id(路徑參數)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payment-requests/<id>/submit \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

對外應付請款單 KPI 計數

GET/api/v1/payment-requests/stats
payable.read

回應欄位 · data

draftCount
number
submittedCount
number
approvedCount
number
paidCount
number
thisMonthPaidCount
number
thisMonthAmount
number
totalApprovedAmount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/payment-requests/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "draftCount": 0,
    "submittedCount": 0,
    "approvedCount": 0,
    "paidCount": 0,
    "thisMonthPaidCount": 0,
    "thisMonthAmount": 0,
    "totalApprovedAmount": 0
  }
}

由某梯次的

GET/api/v1/payment-requests/supplier-suggestions
payable.create

參數

departureId必填
string· min 1

梯次 id;用於推導該梯次住宿供應商的請款細項建議

回應欄位 · data[]

category
string
description
string
quantity
number
unitPriceTwd
number
totalTwd
number
suggestedPayee
string | null
請求
curl -X GET "https://your-tenant.example.com/api/v1/payment-requests/supplier-suggestions?departureId=<departureId>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "category": "…",
      "description": "…",
      "quantity": 0,
      "unitPriceTwd": 0,
      "totalTwd": 0,
      "suggestedPayee": "…"
    }
  ]
}

/payments

list/search/filter the customer→agency payment ledger

GET/api/v1/payments
payment.read

參數

status選填
string

依金流狀態篩選(如 paid 已收款 / pending 待付 / failed 失敗 / refunded 已退款)

method選填
string

依付款方式篩選(如信用卡、ATM 轉帳)

dateFrom選填
string

收款日期區間起日(YYYY-MM-DD)

dateTo選填
string

收款日期區間迄日(YYYY-MM-DD)

q選填
string

關鍵字搜尋(訂單編號、客戶名稱等)

page選填
integer

頁碼(從 1 起算)

pageSize選填
integer· max 200

每頁筆數(上限 200)

回應欄位 · data

rows
object[]
id
string
orderId
string
orderNumber
string
merchantTradeNo
string
providerTradeNo
string | null
provider
string
paymentMethod
string
amountTwd
number
status
string
refunded
boolean
paidAt
Date | null
createdAt
Date
customerName
string
customerEmail
string
tripTitle
string
total
number
page
number
pageSize
number
請求
curl -X GET https://your-tenant.example.com/api/v1/payments \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "orderId": "…",
        "orderNumber": "…",
        "merchantTradeNo": "…",
        "providerTradeNo": "…",
        "provider": "…",
        "paymentMethod": "…",
        "amountTwd": 0,
        "status": "…",
        "refunded": true,
        "paidAt": null,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "customerName": "…",
        "customerEmail": "…",
        "tripTitle": "…"
      }
    ],
    "total": 0,
    "page": 0,
    "pageSize": 0
  }
}

匯出金流分類帳

GET/api/v1/payments/export
payment.read

參數

status選填
string

依金流狀態篩選(如 paid 已收款 / pending 待付 / failed 失敗 / refunded 已退款)

method選填
string

依付款方式篩選(如信用卡、ATM 轉帳)

dateFrom選填
string

收款日期區間起日(YYYY-MM-DD)

dateTo選填
string

收款日期區間迄日(YYYY-MM-DD)

q選填
string

關鍵字搜尋(訂單編號、客戶名稱等)

回應欄位 · data

rows
object[]
id
string
orderId
string
orderNumber
string
merchantTradeNo
string
providerTradeNo
string | null
provider
string
paymentMethod
string
amountTwd
number
status
string
refunded
boolean
paidAt
Date | null
createdAt
Date
customerName
string
customerEmail
string
tripTitle
string
total
number
truncated
boolean
請求
curl -X GET https://your-tenant.example.com/api/v1/payments/export \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "orderId": "…",
        "orderNumber": "…",
        "merchantTradeNo": "…",
        "providerTradeNo": "…",
        "provider": "…",
        "paymentMethod": "…",
        "amountTwd": 0,
        "status": "…",
        "refunded": true,
        "paidAt": null,
        "createdAt": "2026-06-30T08:00:00.000Z",
        "customerName": "…",
        "customerEmail": "…",
        "tripTitle": "…"
      }
    ],
    "total": 0,
    "truncated": true
  }
}

payment KPI counts

GET/api/v1/payments/stats
payment.read

回應欄位 · data

totalAmount
number
paidCount
number
pendingCount
number
failedCount
number
refundedCount
number
thisMonthAmount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/payments/stats \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "totalAmount": 0,
    "paidCount": 0,
    "pendingCount": 0,
    "failedCount": 0,
    "refundedCount": 0,
    "thisMonthAmount": 0
  }
}

/payouts

派生當月

GET/api/v1/payouts/aggregate
supplier.read

參數

period必填
string· 格式限定

出款月份(YYYY-MM),彙整該月已核准未付的應付

scope必填
enum
guidesupplierstaff

收款對象範圍(guide 領隊嚮導 / supplier 供應商 / staff 員工)

回應欄位 · data[]

payeeType
PayoutPayeeType
payeeRefId
string
payeeName
string
payeeAccountName
string | null
payeeBankCode
string | null
payeeAccountNumber
string | null
grossTwd
number
items
object[]
payableId
string
payableNumber
string
date
string | null
tripLabel
string | null
amountTwd
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/payouts/aggregate?period=<period>&scope=<scope>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "payeeType": "…",
      "payeeRefId": "…",
      "payeeName": "…",
      "payeeAccountName": "…",
      "payeeBankCode": "…",
      "payeeAccountNumber": "…",
      "grossTwd": 0,
      "items": [
        {
          "payableId": "…",
          "payableNumber": "…",
          "date": "…",
          "tripLabel": "…",
          "amountTwd": 0
        }
      ]
    }
  ]
}

建立出款批次草稿

POST/api/v1/payouts/batches
supplier.read

參數

period必填
string· 格式限定

出款月份(YYYY-MM)

payeeScope必填
enum

收款對象範圍(guide 領隊嚮導 / supplier 供應商 / staff 員工)

paidFromAccountId選填
string· min 1

出帳帳戶 id(從哪個收款帳戶付出);可留空待確認時指定

lines必填
array· min 1

納入批次的出款列(至少一列)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/payouts/batches \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "period": "<period>",
    "payeeScope": "<payeeScope>",
    "lines": []
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

確認出款批次

POST/api/v1/payouts/batches/{id}/confirm
payable.mark_paid

參數

id路徑
string· 格式限定

出款批次 id(路徑參數,格式 pob_…)

bankReference選填
string· max 64

網銀交易序號 / 轉帳憑證號(可選)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/payouts/batches/<id>/confirm \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

出款批次的標準四欄批次轉帳檔

GET/api/v1/payouts/batches/{id}/transfer-file
payable.mark_paid

參數

id路徑
string· min 1

出款批次 id(路徑參數)

format選填
enum
csvjson

輸出格式:json 完整匯出(預設)或 csv 僅回傳轉帳檔字串

請求
curl -X GET https://your-tenant.example.com/api/v1/payouts/batches/<id>/transfer-file \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": "…"
}

為某出款批次列簽發廠商自助確認

POST/api/v1/payouts/lines/{lineId}/confirm-token
supplier.read

參數

lineId路徑
string· 格式限定

出款批次列 id(路徑參數,格式 pobl_…)

回應欄位 · data

token
string
請求
curl -X POST https://your-tenant.example.com/api/v1/payouts/lines/<lineId>/confirm-token \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "token": "…"
  }
}

出款批次的「出帳帳戶」選項

GET/api/v1/payouts/remit-accounts
supplier.read

回應欄位 · data[]

id
string
code
string
displayName
string
kind
ReceivingAccountKind
bankName
string | null
accountNo
string | null
canReceive
boolean
canRemit
boolean
canChargeback
boolean
isDeprecated
boolean
isSettlementMaster
boolean
currency
string
isActive
boolean
displayOrder
number
usedCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/payouts/remit-accounts \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "displayName": "…",
      "kind": "…",
      "bankName": "…",
      "accountNo": "…",
      "canReceive": true,
      "canRemit": true,
      "canChargeback": true,
      "isDeprecated": true,
      "isSettlementMaster": true,
      "currency": "…",
      "isActive": true,
      "displayOrder": 0,
      "usedCount": 0,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

/pnl

list the company expense-category

GET/api/v1/pnl/expense-categories
operating_expense.read

參數

activeOnly選填
boolean

是否只回傳啟用中的費用類別;預設含停用列

回應欄位 · data[]

id
string
code
string
displayName
string
kind
"opex" | "tax" | "platform_fee" | "special"
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/pnl/expense-categories \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "displayName": "…",
      "kind": "opex",
      "isActive": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

list company operating-expense ledger rows

GET/api/v1/pnl/expenses
operating_expense.read

參數

period選填
string

歸屬月(格式 YYYY-MM);只列出該月的費用

category選填
string

費用類別 ID;只列出該類別的費用

kind選填
enum
opextaxplatform_feespecial

費用大類:opex 營業費用、tax 稅、platform_fee 平台手續費、special 特殊損益

回應欄位 · data[]

id
string
categoryId
string
categoryCode
string | null
categoryDisplayName
string | null
categoryKind
string | null
period
string
incurredOn
string | null
amountTwd
number
description
string
paidFromAccountId
string | null
paidFromAccountName
string | null
frontedByUserId
string | null
frontedByName
string | null
payableId
string | null
payableNumber
string | null
recurring
boolean
note
string | null
createdByUserId
string
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/pnl/expenses \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "categoryId": "…",
      "categoryCode": "…",
      "categoryDisplayName": "…",
      "categoryKind": "…",
      "period": "…",
      "incurredOn": "…",
      "amountTwd": 0,
      "description": "…",
      "paidFromAccountId": "…",
      "paidFromAccountName": "…",
      "frontedByUserId": "…",
      "frontedByName": "…",
      "payableId": "…",
      "payableNumber": "…",
      "recurring": true,
      "note": "…",
      "createdByUserId": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/pnl/expenses
operating_expense.manage模組:accounting

參數

categoryId必填
string· min 1

費用類別 ID(對應公司費用類別目錄)

period必填
string· 格式限定

歸屬月(格式 YYYY-MM),供月損益表彙整

description必填
string· min 1

費用摘要

amountTwd必填
integer

費用金額(台幣非負整數)

incurredOn選填
string

費用發生日期(格式 YYYY-MM-DD)

paidFromAccountId選填
string

支付來源帳戶 ID

frontedByUserId選填
string

代墊人使用者 ID(由員工先行墊付時填寫)

note選填
string

備註

recurring選填
boolean

是否為週期性費用

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/pnl/expenses \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "categoryId": "<categoryId>",
    "period": "<period>",
    "description": "<description>",
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

更正一筆公司營業費用

PATCH/api/v1/pnl/expenses/{id}
operating_expense.manage模組:accounting

參數

categoryId必填
string· min 1

費用類別 ID(對應公司費用類別目錄)

period必填
string· 格式限定

歸屬月(格式 YYYY-MM),供月損益表彙整

description必填
string· min 1

費用摘要

amountTwd必填
integer

費用金額(台幣非負整數)

incurredOn選填
string

費用發生日期(格式 YYYY-MM-DD)

paidFromAccountId選填
string

支付來源帳戶 ID

frontedByUserId選填
string

代墊人使用者 ID(由員工先行墊付時填寫)

note選填
string

備註

recurring選填
boolean

是否為週期性費用

id路徑
string· min 1

營業費用列 ID

payableId選填
string

關聯的請款核簽 ID;整列覆寫時須原樣帶回,省略則清為 null

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/pnl/expenses/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "categoryId": "<categoryId>",
    "period": "<period>",
    "description": "<description>",
    "amountTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the company monthly P&L statement

GET/api/v1/pnl/statement
operating_expense.read

參數

period必填
string· 格式限定

損益表結算月(格式 YYYY-MM)

extraIncome選填
integer

額外收入(台幣非負整數),併入公司淨利計算;預設 0

回應欄位 · data

period
string
regions
object[]
region
string
label
string
revenueTwd
number
directCostTwd
number
marginTwd
number
departures
number
grossMarginTwd
number
revenueTotalTwd
number
extraIncomeTwd
number
adminFeeIncomeTwd
number
otherIncomeTwd
number
expensesByKind
object[]
kind
string
amountTwd
number
count
number
operatingExpenseTotalTwd
number
special
object[]
id
string
categoryId
string
categoryDisplayName
string | null
description
string
amountTwd
number
specialTotalTwd
number
netProfitTwd
number
netMarginPct
number | null
請求
curl -X GET "https://your-tenant.example.com/api/v1/pnl/statement?period=<period>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "period": "…",
    "regions": [
      {
        "region": "…",
        "label": "…",
        "revenueTwd": 0,
        "directCostTwd": 0,
        "marginTwd": 0,
        "departures": 0
      }
    ],
    "grossMarginTwd": 0,
    "revenueTotalTwd": 0,
    "extraIncomeTwd": 0,
    "adminFeeIncomeTwd": 0,
    "otherIncomeTwd": 0,
    "expensesByKind": [
      {
        "kind": "…",
        "amountTwd": 0,
        "count": 0
      }
    ],
    "operatingExpenseTotalTwd": 0,
    "special": [
      {
        "id": "…",
        "categoryId": "…",
        "categoryDisplayName": "…",
        "description": "…",
        "amountTwd": 0
      }
    ],
    "specialTotalTwd": 0,
    "netProfitTwd": 0,
    "netMarginPct": 0
  }
}

/reconciliation

逐收款帳戶現金進出對帳

GET/api/v1/reconciliation/accounts
receiving_account.read

參數

dateFrom選填
string

對帳期間起日(YYYY-MM-DD,含當日),以 Asia/Taipei 牆鐘日界計;省略則不設下界

dateTo選填
string

對帳期間迄日(YYYY-MM-DD,含整日),以 Asia/Taipei 牆鐘日界計;省略則不設上界

回應欄位 · data[]

accountId
string | null
code
string | null
displayName
string | null
kind
ReceivingAccountKind | null
inTwd
number
outTwd
number
payableOutTwd
number
netTwd
number
txCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/accounts \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "accountId": "…",
      "code": "…",
      "displayName": "…",
      "kind": null,
      "inTwd": 0,
      "outTwd": 0,
      "payableOutTwd": 0,
      "netTwd": 0,
      "txCount": 0
    }
  ]
}

未結掛帳追蹤

GET/api/v1/reconciliation/obligations
account_settlement.read

參數

period選填
string

月結來源期間(YYYY-MM),篩選由該期月結互抵推導出的掛帳;省略則不限期間

reason選填
string

掛帳原因代碼,篩選特定成因的掛帳;省略則不限原因

status選填
string

掛帳狀態(如未結清 / 已結清),篩選特定結清狀態;省略則含全部

回應欄位 · data[]

id
string
debtorAccountId
string
creditorAccountId
string
amountTwd
number
settledAmountTwd
number
outstandingTwd
number
reason
ObligationReason
originPeriod
string
status
ObligationStatus
note
string | null
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/obligations \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "debtorAccountId": "…",
      "creditorAccountId": "…",
      "amountTwd": 0,
      "settledAmountTwd": 0,
      "outstandingTwd": 0,
      "reason": "…",
      "originPeriod": "…",
      "status": "…",
      "note": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

收款帳戶目錄清單

GET/api/v1/reconciliation/receiving-accounts
receiving_account.read

參數

activeOnly選填
boolean

是否只回傳啟用中的收款帳戶(true/false);省略則含停用

回應欄位 · data[]

id
string
code
string
displayName
string
kind
ReceivingAccountKind
bankName
string | null
accountNo
string | null
canReceive
boolean
canRemit
boolean
canChargeback
boolean
isDeprecated
boolean
isSettlementMaster
boolean
currency
string
isActive
boolean
displayOrder
number
usedCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/receiving-accounts \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "displayName": "…",
      "kind": "…",
      "bankName": "…",
      "accountNo": "…",
      "canReceive": true,
      "canRemit": true,
      "canChargeback": true,
      "isDeprecated": true,
      "isSettlementMaster": true,
      "currency": "…",
      "isActive": true,
      "displayOrder": 0,
      "usedCount": 0,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

退款執行清單

GET/api/v1/reconciliation/refund-executions
account_settlement.read

參數

status選填
enum
approvedpaid

退款狀態篩選:approved 待執行(已核准)、paid 已執行(已出款);省略則合併回傳兩者

回應欄位 · data

rows
object[]
id
string
refundNumber
string
orderId
string
orderNumber
string | null
status
RefundStatus
refundKind
RefundKind
affectsReceivable
boolean
amountTwd
number
method
RefundMethod
reason
string
createdAt
Date
paidAt
Date | null
createdByName
string | null
executionMethod
RefundExecutionMethod | null
originAccountId
string | null
adminFeeTwd
number
remitFeeTwd
number
payeeAccountName
string | null
payeeBankCode
string | null
payeeAccountNumber
string | null
total
number
請求
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/refund-executions \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "refundNumber": "…",
        "orderId": "…",
        "orderNumber": "…",
        "status": "…",
        "refundKind": "…",
        "affectsReceivable": true,
        "amountTwd": 0,
        "method": "…",
        "reason": "…",
        "createdAt": "2026-06-30T08:00:00.000Z",
        "paidAt": null,
        "createdByName": "…",
        "executionMethod": null,
        "originAccountId": "…",
        "adminFeeTwd": 0,
        "remitFeeTwd": 0,
        "payeeAccountName": "…",
        "payeeBankCode": "…",
        "payeeAccountNumber": "…"
      }
    ],
    "total": 0
  }
}

子系統 B 月結互抵派生總覽

GET/api/v1/reconciliation/settlement-overview
account_settlement.read

參數

period必填
string· 格式限定

要查詢月結互抵總覽的結算期(YYYY-MM)

回應欄位 · data

period
string
matrix
object
lines
object[]
unclassified
object
obligations
object[]
id
string
debtorAccountId
string
creditorAccountId
string
amountTwd
number
settledAmountTwd
number
outstandingTwd
number
reason
ObligationReason
originPeriod
string
status
ObligationStatus
note
string | null
createdAt
Date
updatedAt
Date
請求
curl -X GET "https://your-tenant.example.com/api/v1/reconciliation/settlement-overview?period=<period>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "period": "…",
    "matrix": {
      "lines": [],
      "unclassified": "…"
    },
    "obligations": [
      {
        "id": "…",
        "debtorAccountId": "…",
        "creditorAccountId": "…",
        "amountTwd": 0,
        "settledAmountTwd": 0,
        "outstandingTwd": 0,
        "reason": "…",
        "originPeriod": "…",
        "status": "…",
        "note": "…",
        "createdAt": "2026-06-30T08:00:00.000Z",
        "updatedAt": "2026-06-30T08:00:00.000Z"
      }
    ]
  }
}

跑當期月結互抵派生 + upsert

POST/api/v1/reconciliation/settlement/compute
account_settlement.read

參數

period必填
string· 格式限定

要計算月結互抵的結算期(YYYY-MM),可重跑且冪等(不回退已結額)

回應欄位 · data

period
string
matrix
object
lines
object[]
unclassified
object
upserts
object[]
debtorAccountId
string
creditorAccountId
string
derivedAmountTwd
number
appliedAmountTwd
number
obligationId
string
action
"created" | "updated" | "floored_to_settled"
adjustmentTwd
number
adjustmentObligationId
string | null
deletedObligationIds
string[]
請求
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/settlement/compute \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "period": "<period>"
  }'
回應
{
  "ok": true,
  "data": {
    "period": "…",
    "matrix": {
      "lines": [],
      "unclassified": "…"
    },
    "upserts": [
      {
        "debtorAccountId": "…",
        "creditorAccountId": "…",
        "derivedAmountTwd": 0,
        "appliedAmountTwd": 0,
        "obligationId": "…",
        "action": "created",
        "adjustmentTwd": 0,
        "adjustmentObligationId": "…"
      }
    ],
    "deletedObligationIds": [
      "…"
    ]
  }
}

帳戶間移轉統一分類帳查詢

GET/api/v1/reconciliation/transfers
account_settlement.read

參數

kind選填
string

移轉類型篩選(fx_conversion 換匯 / replenishment 補款 / advance 代墊 / backfill 回填 / refund_payout 退款匯出 / reversal 沖正);省略則含全部

account選填
string

帳戶 ID 篩選,回傳該帳戶為出帳或進帳方的移轉;省略則不限帳戶

dateFrom選填
string

移轉日期起日(YYYY-MM-DD,含當日);省略則不設下界

dateTo選填
string

移轉日期迄日(YYYY-MM-DD,含當日);省略則不設上界

settlementPeriod選填
string

對應月結期間(YYYY-MM)篩選;省略則不限月結

obligation選填
string

掛帳 ID 篩選,回傳沖減該筆掛帳的移轉;省略則不限掛帳

回應欄位 · data[]

id
string
kind
AccountTransferKind
fromAccountId
string | null
toAccountId
string | null
amountTwd
number
feeTwd
number
currency
string | null
foreignAmount
number | null
feeForeign
number | null
grossRate
string | null
settlementPeriod
string | null
obligationId
string | null
reversesTransferId
string | null
occurredAt
string
note
string | null
createdByUserId
string
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/reconciliation/transfers \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "kind": "…",
      "fromAccountId": "…",
      "toAccountId": "…",
      "amountTwd": 0,
      "feeTwd": 0,
      "currency": "…",
      "foreignAmount": 0,
      "feeForeign": 0,
      "grossRate": "…",
      "settlementPeriod": "…",
      "obligationId": "…",
      "reversesTransferId": "…",
      "occurredAt": "…",
      "note": "…",
      "createdByUserId": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/reconciliation/transfers
account_transfer.manage模組:accounting

參數

kind選填
enum· 前處理正規化(省略則補預設 / null)

移轉類型:fx_conversion 換匯、replenishment 補款、advance 代墊、backfill 回填、refund_payout 退款匯出、reversal 沖正

fromAccountId選填
string· min 1 · 前處理正規化

出帳(轉出)帳戶 ID;與進帳帳戶至少填一個,null 表示無出帳方

toAccountId選填
string· min 1 · 前處理正規化

進帳(轉入)帳戶 ID;與出帳帳戶至少填一個,null 表示無進帳方

amountTwd選填
integer· 前處理正規化(省略則補預設 / null)

移轉台幣淨額(整數,不可為負);沖減掛帳時須大於 0

feeTwd選填
integer· 前處理正規化(省略則補預設 / null)

此筆移轉產生的手續費(台幣整數,不可為負)

occurredAt選填
string· 格式限定 · 前處理正規化

移轉發生日期(YYYY-MM-DD)

settlementPeriod選填
string· 格式限定 · 前處理正規化

對應月結期間(YYYY-MM),標記此移轉沖減哪一期互抵;換匯不掛單一月結,傳 null

currency選填
string· 格式限定 · 前處理正規化

換匯外幣幣別(ISO 4217 三碼);非換匯傳 null

foreignAmount選填
integer· 前處理正規化(省略則補預設 / null)

換匯外幣金額(整數最小單位,須大於 0);非換匯傳 null

grossRate選填
string· 格式限定 · 前處理正規化

換匯牌價(正數,最多 6 位小數,以字串表達避免精度遺失);非換匯傳 null

obligationId選填
string· 格式限定 · 前處理正規化

選填沖減的掛帳 ID(aob_ 開頭);換匯不沖減掛帳須傳 null

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/reconciliation/transfers \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/reports

tenant monthly

GET/api/v1/reports/monthly
order.read

參數

year必填
integer· max 2100 · min 2000

報表年份(西元四位數),月界以台北時區計

month必填
integer· max 12 · min 1

報表月份,1 至 12

回應欄位 · data

year
number
month
number
totalOrders
number
paidOrders
number
cancelledOrders
number
totalRevenue
number
refundedAmount
number
netCash
number
newCustomers
number
byTrip
object[]
tripId
string
tripTitle
string
orderCount
number
revenue
number
byProvider
object[]
provider
string
orderCount
number
amount
number
請求
curl -X GET "https://your-tenant.example.com/api/v1/reports/monthly?year=<year>&month=<month>" \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "year": 0,
    "month": 0,
    "totalOrders": 0,
    "paidOrders": 0,
    "cancelledOrders": 0,
    "totalRevenue": 0,
    "refundedAmount": 0,
    "netCash": 0,
    "newCustomers": 0,
    "byTrip": [
      {
        "tripId": "…",
        "tripTitle": "…",
        "orderCount": 0,
        "revenue": 0
      }
    ],
    "byProvider": [
      {
        "provider": "…",
        "orderCount": 0,
        "amount": 0
      }
    ]
  }
}

/roles

list all roles

GET/api/v1/roles
role.manage

參數

system選填
enum
truefalse

是否只列內建角色:true 僅內建、false 僅自訂,省略則全部

回應欄位 · data[]

id
string
name
string
label
string
isSystem
boolean
permissionCount
number
memberCount
number
請求
curl -X GET https://your-tenant.example.com/api/v1/roles \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…",
      "label": "…",
      "isSystem": true,
      "permissionCount": 0,
      "memberCount": 0
    }
  ]
}
POST/api/v1/roles
role.manage

參數

name必填
string

角色代碼,小寫英數與底線、2–32 字且須以字母開頭,建立後不可改

label必填
string

角色顯示名稱,呈現於後台角色清單

permissions選填
array

此角色授予的權限清單,每筆為一組資源與動作

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/roles \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>",
    "label": "<label>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

one role + its full

GET/api/v1/roles/{id}
role.manage

參數

id路徑
string· min 1

角色 ID(內建角色為其代碼)

回應欄位 · data

id
string
name
string
label
string
isSystem
boolean
permissions
object[]
resource
string
action
string
請求
curl -X GET https://your-tenant.example.com/api/v1/roles/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "name": "…",
    "label": "…",
    "isSystem": true,
    "permissions": [
      {
        "resource": "…",
        "action": "…"
      }
    ]
  }
}
PATCH/api/v1/roles/{id}
role.manage

參數

id路徑
string· min 1

欲更新的角色 ID

label必填
string

角色顯示名稱,呈現於後台角色清單

permissions選填
array

完整取代後的權限清單,會整批覆寫此角色現有權限

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/roles/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "<label>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/roles/{id}
role.manage

參數

id路徑
string· min 1

角色 ID(內建角色為其代碼)

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/roles/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the code-defined permission catalog: every legal

GET/api/v1/roles/catalog
role.manage

回應欄位 · data[]

resource
string
actions
string[]
請求
curl -X GET https://your-tenant.example.com/api/v1/roles/catalog \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "resource": "…",
      "actions": [
        "…"
      ]
    }
  ]
}

/rooms

指派旅客進房

POST/api/v1/rooms/{roomId}/travelers
departure.update

參數

roomId路徑
string· min 1

目標房間 ID,旅客將被指派入住此房

travelerId必填
string· min 1

欲指派的旅客 ID,須與房間屬於同一梯次

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/rooms/<roomId>/travelers \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "travelerId": "<travelerId>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

把旅客移出房間

DELETE/api/v1/rooms/travelers/{travelerId}
departure.update

參數

travelerId路徑
string· min 1

欲移出房間的旅客 ID

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/rooms/travelers/<travelerId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/settings

the tenant_settings singleton

GET/api/v1/settings
role.manage

回應欄位 · data

id
string
companyName
string | null
companyPhone
string | null
taxId
string | null
companyAddress
string | null
logoUrl
string | null
siteTagline
string | null
seoDefaultDescription
string | null
ogImageUrl
string | null
emailReplyTo
string | null
assignmentMode
string
defaultAssigneeUserId
string | null
passportExpiryWarningDays
number
ecpayFeeBps
number
fongshouFeeBps
number
profitTaxBps
number
ecpayMerchantId
string | null
ecpaySecretsMask
string | null
sendingDomain
string | null
resendDomainId
string | null
sendingDomainStatus
string | null
senderLocalPart
string | null
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/settings \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "companyName": "…",
    "companyPhone": "…",
    "taxId": "…",
    "companyAddress": "…",
    "logoUrl": "…",
    "siteTagline": "…",
    "seoDefaultDescription": "…",
    "ogImageUrl": "…",
    "emailReplyTo": "…",
    "assignmentMode": "…",
    "defaultAssigneeUserId": "…",
    "passportExpiryWarningDays": 0,
    "ecpayFeeBps": 0,
    "fongshouFeeBps": 0,
    "profitTaxBps": 0,
    "ecpayMerchantId": "…",
    "ecpaySecretsMask": "…",
    "sendingDomain": "…",
    "resendDomainId": "…",
    "sendingDomainStatus": "…",
    "senderLocalPart": "…",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
PATCH/api/v1/settings
role.manage

參數

companyName選填
string· max 200

公司全名,顯示於發票、合約與對外信件抬頭;傳 null 或空字串清除

companyPhone選填
string· max 40

公司聯絡電話,顯示於對外文件;傳 null 或空字串清除

taxId選填
value

公司統一編號(8 位數字),用於開立發票;傳 null 或空字串清除

companyAddress選填
string· max 500

公司登記地址,顯示於對外文件;傳 null 或空字串清除

logoUrl選填
value

公司 Logo 圖片網址(http/https),用於後台與對外頁面品牌呈現;傳 null 或空字串清除

emailReplyTo選填
value

系統寄信時的回覆收件信箱,客戶回信會寄到此處;傳 null 或空字串清除

senderLocalPart選填
value

寄件人信箱的帳號部分(@ 前段),與寄件網域組成完整寄件地址;傳 null 或空字串清除

passportExpiryWarningDays選填
integer· max 3650 · min 1

護照到期前提早幾天提醒(1 至 3650 天),用於行前護照效期預警

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the staff pool eligible to be an

GET/api/v1/settings/assignable-staff
role.manage

回應欄位 · data[]

userId
string
name
string
email
string
role
string
thisMonthAssigned
number
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/assignable-staff \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "userId": "…",
      "name": "…",
      "email": "…",
      "role": "…",
      "thisMonthAssigned": 0
    }
  ]
}

S5 order-assignment mode + default

PATCH/api/v1/settings/assignment
role.manage

參數

assignmentMode必填
enum
auto_round_robinauto_customer_choicemanual_review

訂單指派模式:auto_round_robin 輪流自動指派、auto_customer_choice 依客戶選擇指派、manual_review 進待審由人工指派

defaultAssigneeUserId選填
string

預設承辦人員的使用者 ID,自動指派找不到對象時的兜底承辦人;空字串表示不設預設

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/assignment \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "assignmentMode": "auto_round_robin"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
PUT/api/v1/settings/ecpay-credentials
role.manage

參數

merchantId必填
string· max 20 · min 1

綠界 ECPay 特店編號(MerchantID),用於金流請款與簽章

hashKey必填
string· max 100 · min 1

綠界 ECPay HashKey,CheckMacValue 簽章用密鑰;寫入後即 KMS 加密儲存且永不回傳

hashIv必填
string· max 100 · min 1

綠界 ECPay HashIV,CheckMacValue 簽章用初始向量;寫入後即 KMS 加密儲存且永不回傳

回應欄位 · data

ok
boolean
請求
curl -X PUT https://your-tenant.example.com/api/v1/settings/ecpay-credentials \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "<merchantId>",
    "hashKey": "<hashKey>",
    "hashIv": "<hashIv>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}
DELETE/api/v1/settings/ecpay-credentials
role.manage

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/settings/ecpay-credentials \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

公司營業費用類別目錄

GET/api/v1/settings/expense-categories
operating_expense.read

參數

activeOnly選填
boolean

是否只回傳啟用中的費用類別(true/false);省略則含停用

回應欄位 · data[]

id
string
code
string
displayName
string
kind
"opex" | "tax" | "platform_fee" | "special"
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/expense-categories \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "displayName": "…",
      "kind": "opex",
      "isActive": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/settings/expense-categories
operating_expense.manage

參數

code必填
string· 格式限定 · max 40 · min 1

費用類別代碼(小寫英數與底線),建立後不可變更,作為類別的穩定識別

displayName必填
string· max 100 · min 1

費用類別顯示名稱,呈現於後台費用登錄與報表

kind必填
enum

費用類別種類:opex 營業費用、tax 稅務、platform_fee 平台手續費、special 特殊,影響損益表歸類

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/settings/expense-categories \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "displayName": "<displayName>",
    "kind": "<kind>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

更新費用類別的顯示名 / kind +

PATCH/api/v1/settings/expense-categories/{id}
operating_expense.manage

參數

id路徑
string· min 1

費用類別 ID(路徑參數),指定要更新的類別

displayName必填
string· max 100 · min 1

費用類別顯示名稱,呈現於後台費用登錄與報表

kind必填
enum

費用類別種類:opex 營業費用、tax 稅務、platform_fee 平台手續費、special 特殊,影響損益表歸類

isActive必填
boolean

是否啟用此費用類別;false 為停用(停用而非刪除)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/expense-categories/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "<displayName>",
    "kind": "<kind>",
    "isActive": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

toggle a費用類別

PATCH/api/v1/settings/expense-categories/{id}/active
operating_expense.manage

參數

id路徑
string· min 1

費用類別 ID(路徑參數),指定要切換啟用狀態的類別

isActive必填
boolean

目標啟用狀態:true 啟用、false 停用(停用而非刪除)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/expense-categories/<id>/active \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

fee-category → final receiving

GET/api/v1/settings/fee-category-routes
receiving_account.manage

回應欄位 · data[]

id
string
feeCategory
string
displayName
string
finalAccountId
string
finalAccountName
string | null
finalAccountCode
string | null
isActive
boolean
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/fee-category-routes \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "feeCategory": "…",
      "displayName": "…",
      "finalAccountId": "…",
      "finalAccountName": "…",
      "finalAccountCode": "…",
      "isActive": true,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
PUT/api/v1/settings/fee-category-routes
receiving_account.manage

參數

feeCategory必填
string· 格式限定 · max 40 · min 1

費用類型代碼(小寫英數與底線),此 upsert 的唯一鍵;決定該手續費類型最終結算到哪個帳戶

displayName必填
string· max 100 · min 1

費用類型路由的顯示名稱,呈現於對帳設定

finalAccountId必填
string· min 1

此費用類型最終結算進的收款帳戶 ID

isActive選填
boolean

是否啟用此費用類型路由;省略則維持預設啟用

回應欄位 · data

id
string
請求
curl -X PUT https://your-tenant.example.com/api/v1/settings/fee-category-routes \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "feeCategory": "<feeCategory>",
    "displayName": "<displayName>",
    "finalAccountId": "<finalAccountId>"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

toggle a fee-category

PATCH/api/v1/settings/fee-category-routes/{id}/active
receiving_account.manage

參數

id路徑
string· min 1

費用類型路由 ID(路徑參數,非 feeCategory 代碼),指定要切換啟用狀態的路由

isActive必填
boolean

目標啟用狀態:true 啟用、false 停用(停用而非刪除)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/fee-category-routes/<id>/active \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "isActive": true
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

internal/external-ledger profit estimate

PATCH/api/v1/settings/ledger-fees
role.manage

參數

ecpayFeeBps選填
value

綠界 ECPay 金流手續費率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更

fongshouFeeBps選填
value

豐收金流手續費率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更

profitTaxBps選填
value

淨利稅率,單位 basis points(0..10000,10000=100%),用於內外帳淨利試算;留空不變更

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/ledger-fees \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the tenant's enabled plan modules

GET/api/v1/settings/modules
role.manage

回應欄位 · data

climbing
boolean
overseas
boolean
lodging
boolean
accounting
boolean
lottery
boolean
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/modules \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "climbing": true,
    "overseas": true,
    "lodging": true,
    "accounting": true,
    "lottery": true
  }
}

the收款帳戶目錄

GET/api/v1/settings/receiving-accounts
receiving_account.manage

參數

activeOnly選填
boolean

是否只回傳啟用中的收款帳戶(true/false);省略則含停用

回應欄位 · data[]

id
string
code
string
displayName
string
kind
ReceivingAccountKind
bankName
string | null
accountNo
string | null
canReceive
boolean
canRemit
boolean
canChargeback
boolean
isDeprecated
boolean
isSettlementMaster
boolean
currency
string
isActive
boolean
displayOrder
number
usedCount
number
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/receiving-accounts \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "code": "…",
      "displayName": "…",
      "kind": "…",
      "bankName": "…",
      "accountNo": "…",
      "canReceive": true,
      "canRemit": true,
      "canChargeback": true,
      "isDeprecated": true,
      "isSettlementMaster": true,
      "currency": "…",
      "isActive": true,
      "displayOrder": 0,
      "usedCount": 0,
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/settings/receiving-accounts
receiving_account.manage

參數

code必填
string· max 40 · min 1

收款帳戶代號,建立後不可變更,作為帳戶的穩定識別

displayName必填
string· max 100 · min 1

收款帳戶顯示名稱,呈現於收款與對帳介面

kind必填
enum
bankcashgateway

帳戶種類:bank 銀行帳戶、cash 現金、gateway 金流閘道

bankName選填
string· max 100

銀行名稱(bank 類別適用);空字串清除

accountNo選填
string· max 50

銀行帳號(bank 類別適用);空字串清除

currency選填
value

帳戶幣別,ISO 4217 三碼(如 TWD / JPY / IDR);空字串預設 TWD,非 TWD 即為外幣池

displayOrder選填
integer· max 9999 · min 0

排序權重(0..9999),數字越小越前面;預設 0

isActive選填
boolean

是否啟用此帳戶;省略維持預設

canReceive選填
boolean

是否可作為收款(進帳)帳戶

canRemit選填
boolean

是否可作為出款(匯出)帳戶

canChargeback選填
boolean

是否可作為退款 / 退刷帳戶

isDeprecated選填
boolean

是否標記為已淘汰(保留歷史紀錄但不再新用)

isSettlementMaster選填
boolean

是否為主結算帳戶;每租戶僅能有一個,月結互抵以此為彙整中心

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/settings/receiving-accounts \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "<code>",
    "displayName": "<displayName>",
    "kind": "bank"
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

update a收款帳戶

PATCH/api/v1/settings/receiving-accounts/{id}
receiving_account.manage

參數

id路徑
string· min 1

收款帳戶 ID(路徑參數),指定要更新的帳戶

displayName必填
string· max 100 · min 1

收款帳戶顯示名稱,呈現於收款與對帳介面

kind必填
enum
bankcashgateway

帳戶種類:bank 銀行帳戶、cash 現金、gateway 金流閘道

bankName選填
string· max 100

銀行名稱(bank 類別適用);空字串清除

accountNo選填
string· max 50

銀行帳號(bank 類別適用);空字串清除

currency選填
value

帳戶幣別,ISO 4217 三碼(如 TWD / JPY / IDR);空字串預設 TWD,非 TWD 即為外幣池

displayOrder必填
integer· max 9999 · min 0

排序權重(0..9999),數字越小越前面

isActive選填
boolean

是否啟用此帳戶;省略維持原值

canReceive選填
boolean

是否可作為收款(進帳)帳戶

canRemit選填
boolean

是否可作為出款(匯出)帳戶

canChargeback選填
boolean

是否可作為退款 / 退刷帳戶

isDeprecated選填
boolean

是否標記為已淘汰(保留歷史紀錄但不再新用)

isSettlementMaster選填
boolean

是否為主結算帳戶;每租戶僅能有一個,月結互抵以此為彙整中心

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/receiving-accounts/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "<displayName>",
    "kind": "bank",
    "displayOrder": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

the tenant's custom email sending-domain

GET/api/v1/settings/sending-domain
role.manage

回應欄位 · data

sendingDomain
string | null
resendDomainId
string | null
sendingDomainStatus
string | null
senderLocalPart
string | null
records
object[]
record
string
name
string
type
string
value
string
ttl選填
string | undefined
status選填
string | undefined
priority選填
number | undefined
請求
curl -X GET https://your-tenant.example.com/api/v1/settings/sending-domain \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "sendingDomain": "…",
    "resendDomainId": "…",
    "sendingDomainStatus": "…",
    "senderLocalPart": "…",
    "records": [
      {
        "record": "…",
        "name": "…",
        "type": "…",
        "value": "…",
        "ttl": "…",
        "status": "…",
        "priority": 0
      }
    ]
  }
}

tear down the tenant's custom

POST/api/v1/settings/sending-domain/disable
role.manage

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/disable \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

provision the tenant's custom

POST/api/v1/settings/sending-domain/enable
role.manage

回應欄位 · data

ok
boolean
domain
string
請求
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/enable \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "domain": "…"
  }
}

re-sync DNS verification status

POST/api/v1/settings/sending-domain/verify
role.manage

回應欄位 · data

ok
boolean
status
string
請求
curl -X POST https://your-tenant.example.com/api/v1/settings/sending-domain/verify \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "status": "…"
  }
}

SEO defaults subset of tenant_settings

PATCH/api/v1/settings/seo
role.manage

參數

siteTagline選填
string· max 120

網站標語,顯示於公開站標題與品牌呈現;空字串清除

seoDefaultDescription選填
string· max 300

SEO 預設頁面描述(meta description),未個別設定的頁面套用此值;空字串清除

ogImageUrl選填
value

社群分享預設縮圖(Open Graph image)網址(http/https);空字串清除

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/settings/seo \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/staff

list every staffer in the tenant DB

GET/api/v1/staff
role.manage

回應欄位 · data[]

userId
string
email
string
name
string
role
string
createdAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/staff \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "userId": "…",
      "email": "…",
      "name": "…",
      "role": "…",
      "createdAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}

remove a staffer

DELETE/api/v1/staff/{userId}
role.manage

參數

userId路徑
string· min 1

欲移除員工身分的使用者 ID(將降為一般顧客)

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/staff/<userId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

change a staffer's role

PATCH/api/v1/staff/{userId}/role
role.manage

參數

userId路徑
string· min 1

欲變更角色的員工使用者 ID

role必填
string

變更後的員工角色(admin/sales/op/accountant),決定權限範圍

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/staff/<userId>/role \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "<role>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

建立一個新員工帳號

POST/api/v1/staff/invite
role.manage

參數

email必填
string · email· max 120

受邀員工的登入 Email,作為帳號識別

name必填
string· max 100 · min 1

員工顯示姓名

role必填
string· min 1

指派的員工角色(admin/sales/op/accountant),決定權限範圍

回應欄位 · data

userId
string
tempPassword
string
email
string
role
string
請求
curl -X POST https://your-tenant.example.com/api/v1/staff/invite \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "<email>",
    "name": "<name>",
    "role": "<role>"
  }'
回應
{
  "ok": true,
  "data": {
    "userId": "…",
    "tempPassword": "…",
    "email": "…",
    "role": "…"
  }
}

/suppliers

廠商目錄列表

GET/api/v1/suppliers
supplier.read模組:accounting

參數

status選填
enum
activeinactiveall

依狀態篩選(active 啟用 / inactive 停用 / all 全部,預設 active)

q選填
string

關鍵字搜尋(廠商名稱或類別)

回應欄位 · data[]

id
string
name
string
categoryHint
string | null
payeeAccountName
string | null
payeeBankCode
string | null
payeeAccountNumber
string | null
status
SupplierStatus
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/suppliers \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…",
      "categoryHint": "…",
      "payeeAccountName": "…",
      "payeeBankCode": "…",
      "payeeAccountNumber": "…",
      "status": "…",
      "createdAt": "2026-06-30T08:00:00.000Z",
      "updatedAt": "2026-06-30T08:00:00.000Z"
    }
  ]
}
POST/api/v1/suppliers
supplier.manage模組:accounting

參數

name必填
string· max 120 · min 1

廠商名稱(出款對象顯示名)

categoryHint選填
string· max 60

類別提示(如住宿、交通、餐飲),供分類與搜尋

payeeAccountName選填
string· max 65

收款戶名(須與銀行帳戶登記名一致)

payeeBankCode選填
string· 格式限定

銀行代號(3~7 碼數字,台銀通用四欄轉帳檔用)

payeeAccountNumber選填
string· 格式限定 · max 20

收款銀行帳號(純數字,write-only 寫入後僅回遮罩)

回應欄位 · data

ok
boolean
id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/suppliers \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "<name>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "id": "…"
  }
}

單一廠商主檔

GET/api/v1/suppliers/{id}
supplier.read

參數

id路徑
string· min 1

廠商 id(路徑參數)

回應欄位 · data

id
string
name
string
categoryHint
string | null
payeeAccountName
string | null
payeeBankCode
string | null
payeeAccountNumber
string | null
status
SupplierStatus
createdAt
Date
updatedAt
Date
請求
curl -X GET https://your-tenant.example.com/api/v1/suppliers/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "name": "…",
    "categoryHint": "…",
    "payeeAccountName": "…",
    "payeeBankCode": "…",
    "payeeAccountNumber": "…",
    "status": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z"
  }
}
PATCH/api/v1/suppliers/{id}
supplier.manage模組:accounting

參數

name選填
string· max 120 · min 1

廠商名稱(出款對象顯示名)

categoryHint選填
string· max 60

類別提示(如住宿、交通、餐飲),供分類與搜尋

payeeAccountName選填
string· max 65

收款戶名(須與銀行帳戶登記名一致)

payeeBankCode選填
string· 格式限定

銀行代號(3~7 碼數字,台銀通用四欄轉帳檔用)

payeeAccountNumber選填
string· 格式限定 · max 20

收款銀行帳號(純數字,write-only 寫入後僅回遮罩)

id路徑
string· min 1

廠商 id(路徑參數)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/suppliers/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

/trips

GET/api/v1/trips
trip.read

參數

status選填
string

依行程狀態篩選(draft 草稿/published 上架/archived 封存)

q選填
string

自由文字搜尋(行程標題/代稱/目的地)

groupCode選填
string

依團號篩選,列出含該團號梯次的行程

回應欄位 · data[]

id
string
slug
string
title
string
destination
string
durationDays
number
priceFromTwd
number
status
TripStatus
updatedAt
Date
isClimbing
boolean
isOverseas
boolean
activeDepartureCount
number
nextDepartureDate
string | null
representativeGroupCode
string | null
請求
curl -X GET https://your-tenant.example.com/api/v1/trips \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "slug": "…",
      "title": "…",
      "destination": "…",
      "durationDays": 0,
      "priceFromTwd": 0,
      "status": "…",
      "updatedAt": "2026-06-30T08:00:00.000Z",
      "isClimbing": true,
      "isOverseas": true,
      "activeDepartureCount": 0,
      "nextDepartureDate": "…",
      "representativeGroupCode": "…"
    }
  ]
}

same core op + audit as the back office

POST/api/v1/trips
trip.manage

參數

slug必填
string· 格式限定

行程網址代稱(slug),用於前台路徑與後台識別,只能小寫英數與連字號

title必填
string· max 200 · min 1

行程標題,顯示於前台與訂單

summary選填
string· max 500

行程摘要,前台列表卡片用的一句話簡介

contentMdx選填
string· max 50000

行程詳細內容(MDX 格式),前台行程頁主文

destination必填
string· max 100 · min 1

目的地名稱

durationDays必填
integer· max 60 · min 1

行程天數

priceFromTwd必填
integer· max 10000000 · min 0

起價(新台幣),前台「OOO 元起」顯示用

directPriceTwd選填
integer

直客定價(新台幣),留空(null)則退回起價繼承

agencyPriceTwd選填
integer

同業定價(新台幣),留空(null)則退回直客/起價繼承

depositMode選填
enum
nonefixedpercent

訂金計算方式(none 不收/fixed 固定金額/percent 百分比)

depositAmountTwd選填
integer

訂金固定金額(新台幣),depositMode 為 fixed 時生效

depositPercent選填
integer

訂金百分比(1–100),depositMode 為 percent 時生效

balanceDueDaysBeforeDeparture選填
integer

尾款應繳截止日(出發前幾天)

feeInclusions選填
array· max 30

費用包含項目清單,每項含勾選狀態(ok)與說明文字(text)

isClimbing選填
boolean

是否為登山團(啟用登山相關模組欄位)

isOverseas選填
boolean

是否為海外團

gradeScore選填
integer· max 100 · min 0

登山難度評分(0–100),null 表示未評級

requiresAlpineExperience選填
boolean

是否需具備高山經驗

gradeLabel選填
string· max 50

難度等級標籤文字

confirmGroupMultiple選填
integer· max 1000 · min 1

成團人數倍數(如國內高山團為 7 的倍數),null 表示不限

restrictedQuotaEnabled選填
boolean

是否啟用每人使用次數限制

quotaPerPersonLimit選填
integer· max 1000 · min 1

每人於限制窗內可使用次數上限,null 表示不限

quotaWindow選填
string· max 50

次數限制的計算窗口

waitlistEnabled選填
boolean

是否開放候補

coverImageUrl選填
string· max 500

行程封面圖網址(http/https)

seoTitle選填
string· max 200

SEO 標題,覆寫前台頁面 title

seoDescription選填
string· max 500

SEO 描述,覆寫前台 meta description

ogImageUrl選填
string· max 500

Open Graph 社群分享圖網址(http/https)

status選填
enum

行程狀態(draft 草稿/published 上架/archived 封存)

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/trips \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "<slug>",
    "title": "<title>",
    "destination": "<destination>",
    "durationDays": 0,
    "priceFromTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

full admin trip detail

GET/api/v1/trips/{id}
trip.read

參數

id路徑
string· min 1

行程 ID(路徑參數)

回應欄位 · data

id
string
slug
string
title
string
summary
string | null
contentMdx
string | null
destination
string
durationDays
number
priceFromTwd
number
coverImageUrl
string | null
status
TripStatus
createdAt
Date
updatedAt
Date
isClimbing
boolean
isOverseas
boolean
gradeScore
number | null
requiresAlpineExperience
boolean
gradeLabel
string | null
feeInclusions
{ ok: boolean; text: string; }[] | null
seoTitle
string | null
seoDescription
string | null
ogImageUrl
string | null
images
object[]
id
string
url
string
caption
string | null
displayOrder
number
departures
object[]
id
string
tripId
string
departureDate
string
returnDate
string
priceTwd
number
capacity
number
bookedCount
number
status
DepartureStatus
notes
string | null
allocationMode
"fcfs" | "lottery"
agencyPriceTwd選填
number | null | undefined
depositMode選填
DepositMode | null | undefined
depositAmountTwd選填
number | null | undefined
depositPercent選填
number | null | undefined
groupCode選填
string | null | undefined
regionCode選填
string | null | undefined
airlineCode選填
string | null | undefined
promoActive選填
boolean | undefined
promoPriceTwd選填
number | null | undefined
promoAgencyPriceTwd選填
number | null | undefined
請求
curl -X GET https://your-tenant.example.com/api/v1/trips/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "id": "…",
    "slug": "…",
    "title": "…",
    "summary": "…",
    "contentMdx": "…",
    "destination": "…",
    "durationDays": 0,
    "priceFromTwd": 0,
    "coverImageUrl": "…",
    "status": "…",
    "createdAt": "2026-06-30T08:00:00.000Z",
    "updatedAt": "2026-06-30T08:00:00.000Z",
    "isClimbing": true,
    "isOverseas": true,
    "gradeScore": 0,
    "requiresAlpineExperience": true,
    "gradeLabel": "…",
    "feeInclusions": "…",
    "seoTitle": "…",
    "seoDescription": "…",
    "ogImageUrl": "…",
    "images": [
      {
        "id": "…",
        "url": "…",
        "caption": "…",
        "displayOrder": 0
      }
    ],
    "departures": [
      {
        "id": "…",
        "tripId": "…",
        "departureDate": "…",
        "returnDate": "…",
        "priceTwd": 0,
        "capacity": 0,
        "bookedCount": 0,
        "status": "…",
        "notes": "…",
        "allocationMode": "fcfs",
        "agencyPriceTwd": 0,
        "depositMode": null,
        "depositAmountTwd": 0,
        "depositPercent": 0,
        "groupCode": "…",
        "regionCode": "…",
        "airlineCode": "…",
        "promoActive": true,
        "promoPriceTwd": 0,
        "promoAgencyPriceTwd": 0
      }
    ]
  }
}
PATCH/api/v1/trips/{id}
trip.manage

參數

id路徑
string· min 1

行程 ID(路徑參數)

slug必填
string· 格式限定

行程網址代稱(slug),用於前台路徑與後台識別,只能小寫英數與連字號

title必填
string· max 200 · min 1

行程標題,顯示於前台與訂單

summary選填
string· max 500

行程摘要,前台列表卡片用的一句話簡介

contentMdx選填
string· max 50000

行程詳細內容(MDX 格式),前台行程頁主文

destination必填
string· max 100 · min 1

目的地名稱

durationDays必填
integer· max 60 · min 1

行程天數

priceFromTwd必填
integer· max 10000000 · min 0

起價(新台幣),前台「OOO 元起」顯示用

directPriceTwd選填
integer

直客定價(新台幣),留空(null)則退回起價繼承

agencyPriceTwd選填
integer

同業定價(新台幣),留空(null)則退回直客/起價繼承

depositMode選填
enum
nonefixedpercent

訂金計算方式(none 不收/fixed 固定金額/percent 百分比)

depositAmountTwd選填
integer

訂金固定金額(新台幣),depositMode 為 fixed 時生效

depositPercent選填
integer

訂金百分比(1–100),depositMode 為 percent 時生效

balanceDueDaysBeforeDeparture選填
integer

尾款應繳截止日(出發前幾天)

feeInclusions選填
array· max 30

費用包含項目清單,每項含勾選狀態(ok)與說明文字(text)

isClimbing選填
boolean

是否為登山團(啟用登山相關模組欄位)

isOverseas選填
boolean

是否為海外團

gradeScore選填
integer· max 100 · min 0

登山難度評分(0–100),null 表示未評級

requiresAlpineExperience選填
boolean

是否需具備高山經驗

gradeLabel選填
string· max 50

難度等級標籤文字

confirmGroupMultiple選填
integer· max 1000 · min 1

成團人數倍數(如國內高山團為 7 的倍數),null 表示不限

restrictedQuotaEnabled選填
boolean

是否啟用每人使用次數限制

quotaPerPersonLimit選填
integer· max 1000 · min 1

每人於限制窗內可使用次數上限,null 表示不限

quotaWindow選填
string· max 50

次數限制的計算窗口

waitlistEnabled選填
boolean

是否開放候補

coverImageUrl選填
string· max 500

行程封面圖網址(http/https)

seoTitle選填
string· max 200

SEO 標題,覆寫前台頁面 title

seoDescription選填
string· max 500

SEO 描述,覆寫前台 meta description

ogImageUrl選填
string· max 500

Open Graph 社群分享圖網址(http/https)

status選填
enum

行程狀態(draft 草稿/published 上架/archived 封存)

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/trips/<id> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "<slug>",
    "title": "<title>",
    "destination": "<destination>",
    "durationDays": 0,
    "priceFromTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

bind / unbind a trip's cost template

PUT/api/v1/trips/{id}/cost-template
cost_template.manage

參數

id路徑
string· min 1

行程 ID(路徑參數)

templateId選填
string· min 1

要綁定的成本範本 ID;null 或省略表示解除綁定

回應欄位 · data

ok
boolean
請求
curl -X PUT https://your-tenant.example.com/api/v1/trips/<id>/cost-template \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{

  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

add a departure to a trip

POST/api/v1/trips/{id}/departures
trip.manage

參數

id路徑
string· min 1

行程 ID(路徑參數),新梯次所屬的行程

departureDate必填
string

出發日期(YYYY-MM-DD)

returnDate必填
string

回程日期(YYYY-MM-DD),須晚於出發日

priceTwd必填
integer· max 10000000 · min 0

梯次直客售價(新台幣)

capacity必填
integer· max 200 · min 1

梯次總名額(座位上限)

agencyPriceTwd選填
integer· max 10000000 · min 0

梯次同業售價(新台幣)

depositMode選填
enum
nonefixedpercent

訂金計算方式(none 不收/fixed 固定金額/percent 百分比)

depositAmountTwd選填
integer· max 10000000 · min 0

訂金固定金額(新台幣),depositMode 為 fixed 時生效

depositPercent選填
integer· max 100 · min 1

訂金百分比(1–100),depositMode 為 percent 時生效

status選填
enum

梯次狀態(selling 銷售中/closed 關閉/cancelled 取消/completed 完成)

regionCode選填
string· 格式限定

團號地區來源碼(2–3 碼大寫英數),用於產生團號,可不指定

airlineCode選填
string· 格式限定

團號航空來源碼(2–3 碼大寫英數),用於產生團號,可不指定

回應欄位 · data

id
string
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/<id>/departures \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "departureDate": "<departureDate>",
    "returnDate": "<returnDate>",
    "priceTwd": 0,
    "capacity": 0
  }'
回應
{
  "ok": true,
  "data": {
    "id": "…"
  }
}

為某梯次預留自家旅宿配套

POST/api/v1/trips/{id}/departures/{depId}/lodging
trip.manage模組:lodging

參數

id路徑
string· min 1

行程 ID(路徑參數),梯次所屬的行程

depId路徑
string· min 1

梯次 ID(路徑參數),要預留旅宿的梯次

propertyId必填
string· min 1

自家旅宿物件 ID

roomTypeId必填
string· min 1

該旅宿的房型 ID

checkIn必填
string· 格式限定

入住日(YYYY-MM-DD)

checkOut必填
string· 格式限定

退房日(YYYY-MM-DD),須晚於入住日

blockUnits必填
integer

整塊預留的房間間數

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/<id>/departures/<depId>/lodging \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "propertyId": "<propertyId>",
    "roomTypeId": "<roomTypeId>",
    "checkIn": "<checkIn>",
    "checkOut": "<checkOut>",
    "blockUnits": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

釋回某梯次的自家旅宿配套預留

DELETE/api/v1/trips/{id}/lodging/{dlId}
trip.manage模組:lodging

參數

id路徑
string· min 1

行程 ID(路徑參數),預留所屬的行程

dlId路徑
string· min 1

梯次旅宿配套預留 ID(路徑參數),要釋回的預留

回應欄位 · data

ok
boolean
請求
curl -X DELETE https://your-tenant.example.com/api/v1/trips/<id>/lodging/<dlId> \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

active cost templates for

GET/api/v1/trips/cost-templates
cost_template.read

參數

status選填
string

成本範本狀態篩選;目前僅回傳啟用中(active)範本

回應欄位 · data[]

id
string
name
string
請求
curl -X GET https://your-tenant.example.com/api/v1/trips/cost-templates \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "…"
    }
  ]
}

group-code lookup over HTTP.

GET/api/v1/trips/departures
trip.read

參數

groupCode選填
string· min 1

完整團號,精確比對單一梯次

groupCodePrefix選填
string· min 1

團號前綴,前綴比對列出多個梯次

請求
curl -X GET https://your-tenant.example.com/api/v1/trips/departures \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": "…"
}

per-row pricing / deposit /

PATCH/api/v1/trips/departures/{departureId}
trip.manage

參數

departureId路徑
string· min 1

梯次 ID(路徑參數)

priceTwd必填
integer· max 10000000 · min 0

梯次直客售價(新台幣)

agencyPriceTwd選填
integer· max 10000000 · min 0

梯次同業售價(新台幣),留空則退回常規定價鏈

depositMode選填
enum
nonefixedpercent

訂金計算方式(none 不收/fixed 固定金額/percent 百分比)

depositAmountTwd選填
integer· max 10000000 · min 0

訂金固定金額(新台幣),depositMode 為 fixed 時生效

depositPercent選填
integer· max 100 · min 1

訂金百分比(1–100),depositMode 為 percent 時生效

promoActive選填
boolean

是否啟用梯次促銷覆寫價

promoPriceTwd選填
integer· max 10000000 · min 1

直客促銷價(新台幣),啟用促銷時必填,null 表示清空

promoAgencyPriceTwd選填
integer· max 10000000 · min 1

同業促銷價(新台幣),null 表示同業退回常規鏈

回應欄位 · data

ok
boolean
請求
curl -X PATCH https://your-tenant.example.com/api/v1/trips/departures/<departureId> \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "priceTwd": 0
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

manual group-code

POST/api/v1/trips/departures/{departureId}/group-code
departure.update

參數

departureId路徑
string· min 1

要覆寫團號的梯次 ID

groupCode必填
string

完整團號,格式為 YY+地區+航空+MMDD+序號(如 26EGTK1010A,自動轉大寫)

回應欄位 · data

ok
boolean
groupCode
string
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/group-code \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "groupCode": "<groupCode>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true,
    "groupCode": "…"
  }
}

auto

POST/api/v1/trips/departures/{departureId}/group-code/generate
departure.update

參數

departureId路徑
string· min 1

要產生團號的梯次 ID

regionCode必填
string

地區碼,2–3 碼大寫英數(自動轉大寫)

airlineCode必填
string

航空碼,2–3 碼大寫英數(自動轉大寫)

departureDate必填
string

出發日期(ISO 格式 YYYY-MM-DD,取 MMDD 組成團號)

回應欄位 · data

groupCode
string
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/group-code/generate \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "regionCode": "<regionCode>",
    "airlineCode": "<airlineCode>",
    "departureDate": "<departureDate>"
  }'
回應
{
  "ok": true,
  "data": {
    "groupCode": "…"
  }
}

change a departure's

POST/api/v1/trips/departures/{departureId}/status
trip.manage

參數

departureId路徑
string· min 1

梯次 ID(路徑參數)

status必填
enum

目標梯次狀態(selling 銷售中/closed 關閉/cancelled 取消/completed 完成)

回應欄位 · data

ok
boolean
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/departures/<departureId>/status \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "<status>"
  }'
回應
{
  "ok": true,
  "data": {
    "ok": true
  }
}

匯出行程

GET/api/v1/trips/export
trip.read

參數

status選填
string

依行程狀態篩選(draft 草稿/published 上架/archived 封存)

q選填
string

自由文字搜尋(行程標題/代稱/目的地)

groupCode選填
string

依團號篩選,匯出含該團號梯次的行程

回應欄位 · data

rows
object[]
id
string
slug
string
title
string
destination
string
durationDays
number
priceFromTwd
number
status
TripStatus
updatedAt
Date
isClimbing
boolean
isOverseas
boolean
activeDepartureCount
number
nextDepartureDate
string | null
representativeGroupCode
string | null
total
number
truncated
boolean
請求
curl -X GET https://your-tenant.example.com/api/v1/trips/export \
  -H "Authorization: Bearer $CAIRN_TOKEN"
回應
{
  "ok": true,
  "data": {
    "rows": [
      {
        "id": "…",
        "slug": "…",
        "title": "…",
        "destination": "…",
        "durationDays": 0,
        "priceFromTwd": 0,
        "status": "…",
        "updatedAt": "2026-06-30T08:00:00.000Z",
        "isClimbing": true,
        "isOverseas": true,
        "activeDepartureCount": 0,
        "nextDepartureDate": "…",
        "representativeGroupCode": "…"
      }
    ],
    "total": 0,
    "truncated": true
  }
}

行程批次匯入 commit:上傳檔

POST/api/v1/trips/import
trip.manage

參數

filename必填
string· min 1

上傳檔名,副檔名須為 .xlsx 或 .csv

contentBase64必填
string· min 1

檔案內容的 base64 編碼字串(上限 5 MB)

回應欄位 · data

filename
string
result
object
importBatchId
string
createdTripCount
number
createdDepartureCount
number
skippedCount
number
errorCount
number
results
object[]
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/import \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "<filename>",
    "contentBase64": "<contentBase64>"
  }'
回應
{
  "ok": true,
  "data": {
    "filename": "…",
    "result": {
      "importBatchId": "…",
      "createdTripCount": 0,
      "createdDepartureCount": 0,
      "skippedCount": 0,
      "errorCount": 0,
      "results": []
    }
  }
}

行程批次匯入 dry-run:上傳檔

POST/api/v1/trips/import/validate
trip.manage

參數

filename必填
string· min 1

上傳檔名,副檔名須為 .xlsx 或 .csv

contentBase64必填
string· min 1

檔案內容的 base64 編碼字串(上限 5 MB)

回應欄位 · data

filename
string
result
object
rows
object[]
summary
object
fileError
string | null
請求
curl -X POST https://your-tenant.example.com/api/v1/trips/import/validate \
  -H "Authorization: Bearer $CAIRN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "<filename>",
    "contentBase64": "<contentBase64>"
  }'
回應
{
  "ok": true,
  "data": {
    "filename": "…",
    "result": {
      "rows": [],
      "summary": "…",
      "fileError": "…"
    }
  }
}

Command Palette

Search for a command to run...