ai-sns.io Kitting API リファレンス ← トップへ

ai-sns.io Kitting — REST API

キッティングセンター管制SaaS の全 REST エンドポイント。応答は原則 JSON。

Base URL: https://aisnsio-kitting.hf.space | 発行: Freeborn Inc.

187エンドポイント
83GET
98POST
6PUT
31ドメイン

規約・認証

成功は {ok:true,...}、失敗は {ok:false,error}。認証区分: 公開 admin subadmin token

POST /api/admin/login      { "password": "..." }            -> { ok, token }
POST /api/subadmin/login   { "email": "...", "password": "..." } -> { ok, token }
# 以降のリクエスト: Authorization: Bearer <token>

ヘルスチェック

Health / mount check.

GET/api/ping公開live 200
Health/mount check returning ok flag, current epoch ms as pong, and mounted:true to verify the routes/ auto-mount works.
レスポンス例
{"ok":true,"pong":1784675483941,"mounted":true}

メトリクス (Metrics/Alerts)

ダッシュボード指標・アラート。

GET/api/metrics/overview公開live 200
Headline KPI cards (revenue forecast, MRR, pipeline, kitting count, gross margin, recurring customers) with display strings byte-matched to the inline demo plus counts derived from live shared collections.
レスポンス例
{"ok":true,"month":"令和8年7月度","revenueForecast":{"display":"¥1.86","unit":"M","total":1860000,"oneTime":930000,"recurring":930000,"deltaPct":12.4},"mrr":{"display":"¥930","unit":"K","amount":930000,"projected":1400000,"invoiceRecurring":550},"pipeline":{"display":"¥6.4","unit":"M","amount":6400000,"deals":3},"kittingMonth":{"display":"412","unit":"台","count":412,"jobs":N,"shipments":N},"grossMargin":{"display":"54.2","unit":"%","bar":54,"pct":54.2},"recurringCustomers":{"display":"2","unit":"社","active":N,"proposed":N,"rows":[{"label":"北斗商事(500台・Intune)","amount":"¥380K/月"}]},"aggregates":{"customers":N,"jobs":N,"shipments":N,"invoices":N}}
GET/api/revenue/mix公開live 200
12-month revenue-mix series (months labels, recurring, onetime 万円 arrays) for #revChart; optional ?months=N trims to last N points.
パラメータ位置必須説明
monthsqueryintegerReturn only the last N points. Must be 1..120 or a 400 is returned. Default = full 12-point series.
レスポンス例
{"ok":true,"months":["25/8","25/9","25/10","25/11","25/12","26/1","26/2","26/3","26/4","26/5","26/6","26/7"],"recurring":[38,40,42,46,46,48,50,50,93,93,140,140],"onetime":[22,65,18,120,34,52,88,93,318,282,60,72]}
GET/api/ops/today公開live 200
Today's operation rows (#todayList): id/time/chip/chipLabel/title/detail/status/statusColor, clipped to length limits.
レスポンス例
{"ok":true,"ops":[{"id":"op-001","time":"09:30","chip":"c-cyan","chipLabel":"作業","title":"北斗商事 交換12台 再キッティング(Intune再登録)","detail":"担当:佐々木 | Zone A | チェックリスト 8/12 完了","status":"進行中","statusColor":"var(--cyan)"}]}
GET/api/alerts公開live 200
Alert list (#alertList) with per-alert action (label/danger/toast) plus lateCount = number of unacked late alerts.
レスポンス例
{"ok":true,"alerts":[{"id":"alert-001","label":"出荷漏れ","late":true,"ack":false,"chip":"c-red","chipLabel":"重大","what":"北斗商事 交換2台 — 予定 07/10 を超過","detail":"...","action":{"label":"対応","danger":true,"toast":"本日出荷便に組込みました…(デモ)"}}],"lateCount":1}
POST/api/alert/:id/ack公開
Mark one alert acknowledged (sets ack=true, acked=timestamp) and returns the updated alert.
パラメータ位置必須説明
idpathstringAlert id from metrics-alerts seed, e.g. 'alert-001'. 404 {ok:false,error:'alert not found'} if unknown.
レスポンス例
{"ok":true,"alert":{"id":"alert-001","label":"出荷漏れ","ack":true,"acked":1710000000000,...}}

端末台帳 (Devices)

IMEI単位の端末台帳 CRUD・検索・一括操作。

GET/api/devices公開live 200
List all devices in the ledger collection (seeded with 178 mulberry(42)-generated records keyed by imei).
レスポンス例
{"ok":true,"devices":[{"imei":"356247446539346","serial":"F2LXD73EB4","asset":"HK-26-1001","model":"iPhone 15","maker":"Apple","cust":"北斗商事","mdm":"Intune","status":"保管中","chip":"c-blue",...}],"count":178}
POST/api/device公開
Create one device from partial input; generates a fresh unique imei if absent, fills defaults via makeDevice.
パラメータ位置必須説明
imeibodystringDevice IMEI (max 40 chars). If omitted, a fresh 35+13-digit imei is generated.
modelbodystringDevice model (max 60), default 'iPhone 16'. iPad-* switches OS defaults.
custbodystringCustomer (max 60), default '社内検証機'.
statusbodystringStatus (max 20), default '入荷待ち'; sets chip color via chipFor.
mdmbodystringMDM platform (max 40), default 'Intune'.
serialbodystringSerial (max 40); defaulted from model prefix + padded index.
assetbodystringAsset tag (max 40), default 'HK-26-<n>'.
batbodynumberBattery %, default 100 (passed through, not clipped).
notebodystringFree note (max 300).
リクエスト
{"imei?":"str","model?":"str","cust?":"str","status?":"str","mdm?":"str","serial?":"str","asset?":"str","bat?":100,"...other device fields":"str"}
レスポンス例
{"ok":true,"device":{"imei":"35...","model":"iPhone 16","cust":"社内検証機","status":"入荷待ち","chip":"c-gray",...}}
POST/api/devices/bulk公開
Create N devices from {model,cust,mdm,status,qty}; returns the created[] array.
パラメータ位置必須説明
qtybodynumberCount to create; clamped to 1..1000. Missing/0 -> 400.
modelbodystringModel applied to all created devices.
custbodystringCustomer applied to all created devices.
mdmbodystringMDM applied to all created devices.
statusbodystringStatus applied to all created devices.
リクエスト
{"qty":5,"model?":"iPhone 16","cust?":"北斗商事","mdm?":"Intune","status?":"保管中"}
レスポンス例
{"ok":true,"created":[{"imei":"35...","model":"iPhone 16",...}],"count":5}
POST/api/device/:imei公開
Update fields of an existing device by imei; imei key is immutable, bat passed raw, other fields clipped, chip recomputed when status changes.
パラメータ位置必須説明
imeipathstringIMEI of the device to update (e.g. seed value 356247446539346).
statusbodystringNew status; triggers chip color recompute via chipFor.
batbodynumberBattery %, assigned raw (not clipped).
notebodystringNote (clipped to 300); all other string fields clipped to 120.
リクエスト
{"status?":"作業中","loc?":"B-05","user?":"佐藤 健","bat?":88,"note?":"str"}
レスポンス例
{"ok":true,"device":{"imei":"356247446539346","status":"作業中","chip":"c-cyan",...}}
POST/api/device/:imei/delete公開
Remove one device by imei from the collection.
パラメータ位置必須説明
imeipathstringIMEI of the device to delete (e.g. seed value 356247446539346).
レスポンス例
{"ok":true,"imei":"356247446539346"}

案件管理 (Jobs)

8段階の案件カード(キッティング工程)。

GET/api/jobs公開live 200
List all job (kanban) cards from the in-memory jobs collection.
レスポンス例
{"ok":true,"jobs":[{"id":"job-001","c":"東成建設","t":"PoC 20台(iPhone 16e・Intune新規)","s":0,"due":"07/22","ch":"c-blue","tag":"新規"}, ...9 cards]}
POST/api/job公開
Create a job card; server assigns id (job-…) and defaults stage to 0.
パラメータ位置必須説明
cbodystringCustomer/company name (clipped to 120 chars)
tbodystringTask/title text (clipped to 300 chars)
sbodynumberStage index, clamped 0-7; defaults to 0 if not finite
duebodystringDue date label e.g. '07/22' (clipped to 40)
chbodystringColor/chip class; defaults 'c-blue' (clipped to 40)
tagbodystringTag label (clipped to 40)
リクエスト
{"c":"string","t":"string","s":0,"due":"string","ch":"c-blue","tag":"string"}
レスポンス例
{"ok":true,"job":{"id":"job-<generated>","c":"...","t":"...","s":0,"due":"...","ch":"c-blue","tag":"..."}}
POST/api/job/:id公開
Update stage/fields of an existing job card; only provided (non-null) fields are changed.
パラメータ位置必須説明
idpathstringJob id e.g. 'job-001'
cbodystringCustomer name (clip 120); updated only if non-null
tbodystringTitle (clip 300); updated only if non-null
sbodynumberStage, clamped 0-7; updated only if non-null
duebodystringDue label (clip 40); updated only if non-null
chbodystringColor class (clip 40); updated only if non-null
tagbodystringTag (clip 40); updated only if non-null
リクエスト
{"c":"string","t":"string","s":3,"due":"string","ch":"c-cyan","tag":"string"} (all optional)
レスポンス例
{"ok":true,"job":{"id":"job-001","c":"...","t":"...","s":3,"due":"...","ch":"...","tag":"..."}}
POST/api/job/:id/delete公開
Delete a job card by id.
パラメータ位置必須説明
idpathstringJob id to delete e.g. 'job-005'
レスポンス例
{"ok":true,"id":"job-005"}

入出荷 (Shipments)

入荷・出荷・在庫ロケーション。

GET/api/shipments公開live 200
List all in/out shipments (入出荷) on the IN/OUT board.
レスポンス例
{"ok":true,"shipments":[{"id":"SHP-0001","late":true,"created":1784673357631,"updated":1784673357631,"date":"07/10","kind":"out","customer":"北斗商事","detail":"交換端末 2台 → 仙台支店…","carrier":"","status":"超過"}]}
POST/api/shipment公開
Create a shipment; server assigns SHP-#### id.
パラメータ位置必須説明
kindbodystring'in' or 'out'; defaults to 'in' if omitted/invalid
customerbodystringCustomer name, clipped to 120 chars; required (400 if empty)
datebodystringDisplay date e.g. '07/13', clipped 40 chars
detailbodystringFree-text detail, clipped 400 chars
carrierbodystringCarrier info, clipped 120 chars
statusbodystringOne of 予定/手配中/出荷済/入荷済/超過/完了; defaults 予定
latebodybooleanOverdue flag; coerced to boolean
リクエスト
{"kind":"out","customer":"三峰精機","date":"07/20","detail":"8台 → 大阪支店","carrier":"ヤマトB2","status":"予定","late":false}
レスポンス例
{"ok":true,"shipment":{"id":"SHP-0007","date":"07/20","kind":"out","customer":"三峰精機","detail":"…","carrier":"ヤマトB2","status":"予定","late":false,"created":1784...,"updated":1784...}}
POST/api/shipment/:id公開
Advance status / update fields of an existing shipment.
パラメータ位置必須説明
idpathstringShipment id e.g. SHP-0001
datebodystringNew display date, clipped 40
kindbodystring'in'/'out'; ignored if invalid
customerbodystringNew customer, clipped 120
detailbodystringNew detail, clipped 400
carrierbodystringNew carrier, clipped 120
statusbodystringMust be valid status (else 400); done statuses clear late flag
latebodybooleanOverdue flag; coerced to boolean
リクエスト
{"status":"出荷済"}
レスポンス例
{"ok":true,"shipment":{"id":"SHP-0001","status":"出荷済","late":false,"updated":1784...}}
POST/api/shipment/:id/delete公開
Delete a shipment by id.
パラメータ位置必須説明
idpathstringShipment id e.g. SHP-0001
レスポンス例
{"ok":true}

ヘルプデスク (Tickets)

サポートチケットと対応履歴。

GET/api/tickets公開live 200
List all support tickets from the tickets collection (seeded with 6 demo tickets TK-0667..TK-0672).
レスポンス例
{"ok":true,"tickets":[{"id":"TK-0672","cust":"北斗商事","kind":"紛失","subject":"営業車内で紛失 → 位置特定&リモートワイプ要請","owner":"佐々木","sla":"1h 12m","status":"対応中"}]}
POST/api/ticket公開
Create a new ticket; auto-assigns id TK-0<next num> (starts at 673) and created timestamp, clips input fields.
パラメータ位置必須説明
custbodystringCustomer name (alias: customer); default '—', clipped to 120.
kindbodystringTicket type; default '問合せ', clipped to 60.
subjectbodystringSubject text; default '', clipped to 300.
ownerbodystringAssigned owner; default '—', clipped to 60.
slabodystringSLA label; default '4h 00m', clipped to 60.
statusbodystringStatus; default '受付', clipped to 40.
prioritybodystringPriority; default '', clipped to 40.
リクエスト
{"cust":"string","kind":"string","subject":"string","owner":"string","sla":"string","status":"string","priority":"string"}
レスポンス例
{"ok":true,"ticket":{"id":"TK-0673","cust":"—","kind":"問合せ","subject":"","owner":"—","sla":"4h 00m","status":"受付","priority":"","created":1700000000000}}
POST/api/ticket/:id公開
Update an existing ticket's status/owner/sla/subject/cust/kind/priority (only provided non-null fields).
パラメータ位置必須説明
idpathstringTicket id, e.g. TK-0672.
statusbodystringNew status, clipped to 40.
ownerbodystringNew owner, clipped to 60.
slabodystringNew SLA label, clipped to 60.
subjectbodystringNew subject, clipped to 300.
custbodystringNew customer, clipped to 120.
kindbodystringNew kind, clipped to 60.
prioritybodystringNew priority, clipped to 40.
リクエスト
{"status":"string","owner":"string","sla":"string","subject":"string","cust":"string","kind":"string","priority":"string"}
レスポンス例
{"ok":true,"ticket":{"id":"TK-0672","status":"解決",...}}
POST/api/ticket/:id/delete公開
Delete a ticket and its associated messages.
パラメータ位置必須説明
idpathstringTicket id to delete, e.g. TK-0672.
レスポンス例
{"ok":true}
GET/api/ticket/:id/messages公開live 200
List all messages for a given ticket (empty array if none recorded).
パラメータ位置必須説明
idpathstringTicket id, e.g. TK-0672.
レスポンス例
{"ok":true,"messages":[]}
POST/api/ticket/:id/message公開
Append a message {from,text} to a ticket's message list; assigns msg id and timestamp.
パラメータ位置必須説明
idpathstringTicket id, e.g. TK-0672.
frombodystringSender label; default '—', clipped to 60.
textbodystringMessage body, clipped to 2000; required (400 if empty).
リクエスト
{"from":"string","text":"string (required)"}
レスポンス例
{"ok":true,"message":{"id":"msg-xxxx","from":"田中","text":"...","ts":1700000000000}}

顧客管理 (Customers)

顧客アカウント・更新・商談。

GET/api/customers公開live 200
List all customer accounts (id, name, industry, mdm, monthly, devices, since, status, note, renew).
レスポンス例
{"ok":true,"customers":[{"id":"cust-mrv8frxlg","key":"hokuto","name":"北斗商事","industry":"大手商社 | 500台(iPhone)","mdm":"Intune(Clomo→移行済)","monthly":"¥380,000","devices":"500 台","since":"2025/04","status":"運用中","statusChip":"c-green","note":"豊島倉庫 専用エリア ¥45K/月","renew":{"date":"2027-03-31",...}}]}
POST/api/customer公開
Create a new customer account; requires name; returns generated id and full record.
パラメータ位置必須説明
namebodystringAccount name (required; 400 if missing)
industrybodystringIndustry / device summary line
mdmbodystringMDM platform
monthlybodystringMonthly fee (default '—')
devicesbodystringDevice count (default '—')
sincebodystringStart month (default '—')
statusbodystringStatus label
statusChipbodystringStatus chip class (default 'c-gray')
notebodystringFree-text note
keybodystringShort account key
renewbodyobjectRenewal/deal object {date,dateLabel,year,kind,kindChip,what,detail,confidence,confColor} or null
リクエスト
{"name":"...","industry":"...","mdm":"...","monthly":"...","devices":"...","since":"...","status":"...","statusChip":"...","note":"...","key":"...","renew":{...}|null}
レスポンス例
{"ok":true,"id":"cust-xxxx","customer":{"id":"cust-xxxx","name":"...","industry":"","mdm":"","monthly":"—","devices":"—","since":"—","status":"","statusChip":"c-gray","note":"","renew":null}}
POST/api/customer/:id公開
Update fields of an existing customer by id; 404 if id not found.
パラメータ位置必須説明
idpathstringCustomer id (e.g. cust-mrv8frxlg)
namebodystringAny of the shape() string fields to update
renewbodyobjectRenewal object or null to overwrite renew
リクエスト
{"name":"...","industry":"...","note":"...","renew":{...}|null, ...any shape fields}
レスポンス例
{"ok":true,"customer":{"id":"cust-mrv8frxlg","name":"...",...}}
POST/api/customer/:id/delete公開
Delete a customer by id; 404 if not present.
パラメータ位置必須説明
idpathstringCustomer id to delete
レスポンス例
{"ok":true,"id":"cust-mrv8frxlg"}
GET/api/renewals公開live 200
Renewal/deal calendar derived from customers with a renew.date; sorted ascending by date.
レスポンス例
{"ok":true,"renewals":[{"id":"ren-cust-mrv8frxli","customerId":"cust-mrv8frxli","customer":"科研製薬","date":"2026-08-31","dateLabel":"08/31","year":"2026","kind":"商談","kindChip":"c-orange","what":"最終見積回答期限","detail":"...","confidence":"確度 80%","confColor":"orange"}]}

見積 (Quote)

見積の作成・改訂・PDF元データ。

GET/api/quote/catalog公開live 200
Returns the constant INITIAL/RUNNING line-item catalog master (mirrors app.html).
レスポンス例
{"ok":true,"catalog":{"initial":[{"n":"プロジェクト管理費","q":1,"p":300000,"d":"..."}, ...],"running":[{"n":"サービス管理・月次報告","q":1,"p":125000,"d":"..."}, ...]}}
GET/api/quotes公開live 200
Lists all saved quotes, each augmented with a computed totals snapshot.
レスポンス例
{"ok":true,"quotes":[{"id":"Q-KAKEN-001","cust":"科研製薬 御中","pattern":"A","costRate":45,"ini":[...],"run":[...],"signId":null,"totals":{"ini":...,"iniTax":...,"iniTotal":...,"run":...,"arr":...,"y1":...}}]}
GET/api/quote/:id公開live 200
Returns one saved quote by id with computed totals, or 404 if not found.
パラメータ位置必須説明
idpathstringQuote id, e.g. 'Q-KAKEN-001'
レスポンス例
{"ok":true,"quote":{"id":"Q-KAKEN-001","cust":"科研製薬 御中","pattern":"A","costRate":45,"ini":[...],"run":[...],"signId":null,"totals":{...}}}
POST/api/quote公開
Saves a new quote with a generated id (Q-...), normalizing line items and totals.
パラメータ位置必須説明
custbodystringCustomer name (clipped 200 chars, defaults '御中')
patternbodystring'A' or 'B' (defaults 'A')
costRatebodynumberCost rate percent (defaults 45)
inibodyarrayInitial line items [{n,q,p,d}]
runbodyarrayRunning line items [{n,q,p,d}]
signIdbodystringOptional linked sign id (clipped 120 chars)
リクエスト
{"cust":"...","pattern":"A","costRate":45,"ini":[{"n":"...","q":1,"p":100,"d":"..."}],"run":[...],"signId":null}
レスポンス例
{"ok":true,"quote":{"id":"Q-...","cust":"...",...,"totals":{...}}}
POST/api/quote/:id公開
Updates an existing quote in place (patch semantics), or 404 if not found.
パラメータ位置必須説明
idpathstringQuote id to update
custbodystringUpdated customer name
patternbodystring'A' or 'B'
costRatebodynumberCost rate; falls back to current if 0/invalid
inibodyarrayInitial line items to replace
runbodyarrayRunning line items to replace
signIdbodystringSign id to link (or null to clear)
リクエスト
{"signId":"S-123"} (any subset of: cust,pattern,costRate,ini,run,signId)
レスポンス例
{"ok":true,"quote":{"id":"Q-KAKEN-001",...,"updatedAt":...,"totals":{...}}}

請求 (Invoices/Billing)

請求書・売上サマリ。

GET/api/invoices公開live 200
List all invoices sorted newest-id first (descending localeCompare on id).
レスポンス例
{"ok":true,"invoices":[{"id":"INV-2607-004","cust":"三峰精機","month":"2607","desc":"新入社員向けキッティング 8台+送料","amount":19800,"due":"08/15","status":"draft","recurring":false}],"count":5}
POST/api/invoice公開
Create an invoice; auto-generates sequential id (INV-YYMM-NNN) unless a fresh INV- id is supplied.
パラメータ位置必須説明
custbodystringCustomer name, trimmed, clipped to 120 chars; 400 if empty.
amountbodynumberInvoice amount; must be finite and >= 0, rounded; 400 if invalid.
statusbodystringOne of draft|issued|paid|overdue; defaults to draft if omitted/invalid.
monthbodystringBilling month YYMM (clip 8); defaults to current YYMM.
descbodystringLine-item description, clip 300.
duebodystringDue date string, clip 20.
idbodystringOptional custom id; used only if matches /^INV-/ and not already present, else auto-assigned.
recurringbodybooleanRecurring flag (coerced to bool).
リクエスト
{"cust":"string(req)","amount":number(req),"status":"draft|issued|paid|overdue","month":"YYMM","desc":"string","due":"string","id":"INV-...","recurring":bool}
レスポンス例
{"ok":true,"invoice":{"id":"INV-2607-005","cust":"北斗商事","month":"2607","desc":"","amount":10000,"due":"","status":"draft","recurring":false}}
POST/api/invoice/:id公開
Update status and/or fields on one existing invoice; validates status enum and amount.
パラメータ位置必須説明
idpathstringInvoice id to update, e.g. INV-2607-004; 404 if not found.
statusbodystringNew status; must be in draft|issued|paid|overdue else 400.
custbodystringCustomer name, clip 120.
descbodystringDescription, clip 300.
monthbodystringBilling month, clip 8.
duebodystringDue date, clip 20.
amountbodynumberAmount; must be finite and >= 0 else 400.
recurringbodybooleanRecurring flag (coerced to bool).
リクエスト
{"status":"...","cust":"string","desc":"string","month":"YYMM","due":"string","amount":number,"recurring":bool} (all optional)
レスポンス例
{"ok":true,"invoice":{"id":"INV-2607-004","cust":"三峰精機","month":"2607","desc":"新入社員向けキッティング 8台+送料","amount":19800,"due":"08/15","status":"issued","recurring":false}}
POST/api/invoices/issue公開
Bulk-issue: flips all draft invoices in a given (or current) month to issued, returns count.
パラメータ位置必須説明
monthbodystringTarget YYMM month, clip 8; defaults to current month (e.g. 2607).
リクエスト
{"month":"YYMM"} (optional; defaults to current month)
レスポンス例
{"ok":true,"count":1}
GET/api/billing/summary公開live 200
Compute billing summary: MRR/ARR, billed/paid/unpaid/overdue/draft totals, recurring:oneshot ratio and paid ratio.
レスポンス例
{"ok":true,"summary":{"mrr":550000,"arr":6600000,"billed":632500,"paid":550000,"unpaid":82500,"overdue":49500,"draft":19800,"recurring":550000,"oneshot":82500,"ratio":"87:13","recurringPct":87,"paidRatio":87,"month":"2607","count":5}}

シフト (Shift)

現場スタッフのシフト計画。

GET/api/shifts公開live 200
Returns the weekly roster grid and today's timeclock state.
レスポンス例
{"ok":true,"grid":{"s1":["day","day","day","day","day","off","off"],...},"clock":{"s1":{"in":"09:00","out":null,"status":"in","units":76},...}}
GET/api/staff公開live 200
Returns the roster staff list (own + agency staff).
レスポンス例
{"ok":true,"staff":[{"id":"s1","name":"佐々木","type":"own"},{"id":"a1","name":"派遣A","type":"agency"}]}
POST/api/shifts公開
Saves the roster grid, and optionally the timeclock, to the store.
パラメータ位置必須説明
gridbodyobjectRoster grid keyed by staffId → array of 7 day-status strings (e.g. 'day','late','off','disp').
clockbodyobjectOptional timeclock object keyed by staffId → {in,out,status,units}.
リクエスト
{"grid":{"s1":["day",...]},"clock":{"s1":{"in":"09:00",...}}}
レスポンス例
{"ok":true,"grid":{...},"clock":{...}}
POST/api/timeclock/:staffId/punch公開
Punches a staff member in or out, updating and returning their timeclock row.
パラメータ位置必須説明
staffIdpathstringStaff id (clipped to 40 chars); must exist in staff roster (e.g. 's1','a1').
dirbodystring'in' or 'out' (clipped to 8 chars); if omitted/invalid, toggles based on current status.
リクエスト
{"dir":"in"}
レスポンス例
{"ok":true,"staffId":"s1","row":{"in":"09:00","out":null,"status":"in","units":76}}

入出荷ドック (Dock)

バース予約・受入スケジュール。

GET/api/dock/reservations公開live 200
List all dock/berth reservations (横づけ枠 weekly schedule data).
レスポンス例
{"ok":true,"reservations":[{"id":"RV-0001","created":1784673357614,"updated":1784673357614,"date":"2026-07-13","start":"10:00","dur":90,"size":"2t車","dir":"入荷","cust":"北斗商事","note":"返却45台","berth":"A","road":"否","roadStatus":"","permit":"済"}]}
POST/api/dock/reservation公開
Upsert a reservation by id (create if id missing/unknown, else update existing).
パラメータ位置必須説明
idbodystringReservation id; if present and known -> update, else create with this id (or auto RV-#### if omitted).
datebodystringReservation date, clipped to 40 chars (e.g. 2026-07-13).
startbodystringStart time HH:MM, clipped to 10 chars.
durbodyintegerDuration minutes, min 15, default 60.
sizebodystringVehicle size; validated against 2t車/4t車/4tロング/大型車 else clipped.
dirbodystringDirection 入荷|出荷; invalid falls back to 入荷.
custbodystringCustomer name (required on create), clipped to 120 chars.
notebodystringFree note, clipped to 300 chars.
berthbodystringBerth A/B/路上待機; invalid falls back to A.
roadbodystringRoad-standby flag 要|否; anything not 要 becomes 否.
roadStatusbodystringRoad-permit status text, clipped to 20 chars (e.g. pending/done).
permitbodystringPermit status text, clipped to 20 chars (e.g. 済/要).
リクエスト
{"id":"RV-0001","date":"2026-07-13","start":"10:00","dur":90,"size":"2t車","dir":"入荷","cust":"北斗商事","note":"返却45台","berth":"A","road":"否","roadStatus":"","permit":"済"}
レスポンス例
{"ok":true,"reservation":{"id":"RV-0001","date":"2026-07-13",..."updated":1784673357614}}
POST/api/dock/reservation/:id/delete公開
Delete a reservation by id.
パラメータ位置必須説明
idpathstringReservation id to delete, e.g. RV-0001.
レスポンス例
{"ok":true}

データ消去証明 (Erasure)

ワイプ実績と消去証明書。

GET/api/certs公開live 200
List all erasure certificates, newest-first.
レスポンス例
{"ok":true,"certs":[{"no":"KIT-ERZ-2026-1003","date":"2026-07-09","cust":"科研製薬(検証)","count":6,"methodKey":"clear","method":"論理消去","nist":"Clear","devices":[...]}]}
GET/api/erasure/certs公開live 200
Alias of /api/certs — list all erasure certificates newest-first.
レスポンス例
{"ok":true,"certs":[{"no":"KIT-ERZ-2026-1003",...}]}
GET/api/cert/:no公開live 200
Fetch a single certificate by its cert number for reprint.
パラメータ位置必須説明
nopathstringCertificate number, e.g. KIT-ERZ-2026-1001
レスポンス例
{"ok":true,"cert":{"no":"KIT-ERZ-2026-1001","date":"2026-07-03","cust":"北斗商事","count":45,"methodKey":"purge","method":"暗号化消去","nist":"Purge","devices":[...]}}
POST/api/cert公開
Issue a new certificate; server auto-numbers via persisted counter.
パラメータ位置必須説明
custbodystringCustomer name (clip 120, trimmed); 400 if empty
methodKeybodystringOne of purge|clear|destroy; 400 if invalid
datebodystringYYYY-MM-DD (clip 10); defaults to today
countbodyintegerDevice count 1-500 when devices[] omitted; defaults 1
devicesbodyarrayOptional device objects {model,id,storage,dt,verify,log,al}; sliced to 500, normalized
リクエスト
{"cust":"string","methodKey":"purge|clear|destroy","date":"YYYY-MM-DD","count":1,"devices":[{"model":"iPhone 16","id":"...","storage":"256GB"}]}
レスポンス例
{"ok":true,"cert":{"no":"KIT-ERZ-2026-1004","date":"2026-07-22","cust":"...","count":1,"methodKey":"purge","method":"暗号化消去","nist":"Purge","devices":[...]}}

リプレース提案 (Replace)

バッテリー劣化・更新提案。

GET/api/replace/proposals公開live 200
Returns the per-customer 'proposed' (提案済み) map for device-refresh bundles as { customer: ISO-timestamp }.
レスポンス例
{"ok":true,"proposals":{}}
POST/api/replace/proposal公開
Marks a customer's device-refresh bundle as proposed (upserts { cust, at:now }) and returns the updated proposals map.
パラメータ位置必須説明
custbodystringCustomer key/name to mark as proposed; clipped to 120 chars. Empty/missing -> 400.
リクエスト
{ "cust": "<customer>" }
レスポンス例
{"ok":true,"cust":"ACME株式会社","at":"2026-07-22T00:00:00.000Z","proposals":{"ACME株式会社":"2026-07-22T00:00:00.000Z"}}

ネットワーク (Network)

拠点回線・機器監視。

GET/api/network/deals公開live 200
Return the capacity-network deal board (provide/accept/request deals), newest-first.
レスポンス例
{"ok":true,"deals":[{"id":"dmrv8fry22c","dir":"provide","partner":"ネットワーク公開","kind":"キッティング枠","units":40,"period":"7/15–7/22","rate":1200,"status":"募集中"}]}
POST/api/network/deal公開
Add a deal to the board (list surplus capacity or request capacity); prepends to deals array.
パラメータ位置必須説明
unitsbodyintegerNumber of units/slots; parsed as int, must be > 0 else 400.
dirbodystringDirection: provide|accept|request; anything else coerced to 'provide' (clipped 16).
partnerbodystringPartner/counterparty name (clipped 120); defaults 'ネットワーク公開'.
kindbodystringCapacity kind (clipped 40); defaults 'キッティング枠'.
periodbodystringDate range label (clipped 40); defaults '—'.
ratebodyintegerUnit rate; parsed int, defaults 0.
statusbodystringStatus label (clipped 24); defaults by dir (承認待ち/対応中/募集中).
リクエスト
{"dir":"provide","partner":"ネットワーク公開","kind":"キッティング枠","units":40,"period":"7/15–7/22","rate":1200,"status":"募集中"}
レスポンス例
{"ok":true,"deal":{"id":"d...","dir":"provide","partner":"...","kind":"キッティング枠","units":40,"period":"—","rate":0,"status":"募集中"},"deals":[...]}
GET/api/network/centers公開live 200
Return the certified kitting-center directory / marketplace (5 seeded centers).
レスポンス例
{"ok":true,"centers":[{"id":"c-tsm","name":"豊島 近接センター","region":"東京","mdm":["Intune","Workspace ONE"],"slots":80,"shelf":40,"rate":1100,"certs":["ISMS","Pマーク"]}]}
GET/api/network/oem公開live 200
Return the white-label / OEM tenant config (brand, logo, domain, plan).
レスポンス例
{"ok":true,"oem":{"brand":"","logo":"","domain":"","plan":"seat"}}
POST/api/network/oem公開
Save the OEM tenant config; overwrites the single 'oem' doc.
パラメータ位置必須説明
brandbodystringBrand name (clipped 24).
logobodystringLogo (clipped 2 chars — likely an emoji/initial).
domainbodystringCustom domain (clipped 48).
planbodystringBilling plan: seat|rev; anything else coerced to 'seat' (clipped 8).
リクエスト
{"brand":"Acme","logo":"A","domain":"acme.example","plan":"seat"}
レスポンス例
{"ok":true,"oem":{"brand":"Acme","logo":"A","domain":"acme.example","plan":"seat"}}

需要予測 (Forecast)

16週の需要・要員シミュレーション。

GET/api/forecast公開live 200
Returns 16-week demand series, transparent demand/staffing model constants, and persisted user prefs (horizon, sim).
レスポンス例
{"ok":true,"weekly":[620,600,540,470,560,690,810,940,980,900,700,600,560,540,600,640],"constants":{"PER_PERSON":80,"BASE_STAFF":2,"WORKDAYS":5,"CEIL_DAY":192,"COST_PER_STAFF":310000,"COST_MONTHS":2,"DEAL_REV":3850000,"DEAL_GROSS":1900000},"prefs":{"horizon":12,"sim":2}}
POST/api/forecast/prefs公開
Persists user prefs; validates horizon in {8,12,16} and sim in {0,1,2}, returns saved prefs.
パラメータ位置必須説明
horizonbodynumberForecast horizon in weeks; must be 8, 12 or 16 else 400
simbodynumberSimulation/scenario index; must be 0, 1 or 2 else 400
リクエスト
{"horizon":12,"sim":2}
レスポンス例
{"ok":true,"prefs":{"horizon":12,"sim":2}}

ラベル・QR (Labels)

管理番号・IMEI・資産QR印刷。

GET/api/labels/templates公開live 200
List all saved label templates.
レスポンス例
{"ok":true,"templates":[]}
POST/api/labels/template公開
Create a new label template with a server-issued id.
パラメータ位置必須説明
namebodystringTemplate name; clipped to 80 chars, defaults to 'テンプレート' if blank after sanitize but request is rejected 400 if missing/whitespace-only.
sizebodystringLabel size, one of s|m|l; defaults to 'm' if invalid.
fieldsbodyobjectBooleans for keys mgmt,imei,cust,model,qr,barcode; coerced to !!value.
tsbodynumberTimestamp; defaults to Date.now().
リクエスト
{"name":"string","size":"s|m|l","fields":{"mgmt":bool,"imei":bool,"cust":bool,"model":bool,"qr":bool,"barcode":bool},"ts":number}
レスポンス例
{"ok":true,"template":{"id":"tpl-xxxx","name":"...","fields":{...},"size":"m","ts":1700000000000}}
POST/api/labels/template/:id/delete公開
Delete a template by id.
パラメータ位置必須説明
idpathstringTemplate id (clipped to 40 chars). Must exist in tplCol.
レスポンス例
{"ok":true,"id":"tpl-xxxx"}
GET/api/labels/log公開live 200
List all print-batch log entries.
レスポンス例
{"ok":true,"log":[]}
POST/api/labels/log公開
Append a print-batch record to the log.
パラメータ位置必須説明
sizebodystringLabel size s|m|l; defaults to 'm' if invalid.
countbodynumberNumber of labels printed; clamped to 0..100000, defaults 0.
datebodystringDate string clipped to 10 chars; defaults to today's ISO date (YYYY-MM-DD).
tsbodynumberTimestamp; defaults to Date.now().
リクエスト
{"size":"s|m|l","count":number,"date":"YYYY-MM-DD","ts":number}
レスポンス例
{"ok":true,"entry":{"id":"lg-xxxx","ts":1700000000000,"date":"2026-07-22","count":0,"size":"m"}}

アンケート (Survey)

CSAT / NPS 回収。

GET/api/survey公開live 200
Return persisted survey state: arrived responses, churn-save followups keyed by response id, and the running sent counter.
レスポンス例
{"ok":true,"responses":[],"followups":{},"sent":152}
POST/api/survey/send公開
Increment the survey-sent counter by {batch} (defaults to 1 if missing/invalid) and return the new total.
パラメータ位置必須説明
batchbodynumberHow many surveys were sent; must be >0 or it defaults to 1.
リクエスト
{"batch": 10}
レスポンス例
{"ok":true,"sent":162}
POST/api/survey/response公開
Append/upsert an arrived survey response (id,date,cust,src,k,nps,csat,comment) into the responses collection.
パラメータ位置必須説明
idbodystringResponse id (clip 60); auto-generated as SR-<id> if absent.
datebodystringResponse date (clip 20), default ''.
custbodystringCustomer name (clip 120), default '—'.
srcbodystringSource channel (clip 20), default 'ticket'.
kbodystringKind/metric type (clip 10), default 'CSAT'.
npsbodynumberNPS score; null if omitted, else coerced with +.
csatbodynumberCSAT score; null if omitted, else coerced with +.
commentbodystringFree-text comment (clip 400), default ''.
リクエスト
{"id":"SR-1001","date":"2026-07-22","cust":"Acme","src":"ticket","k":"CSAT","nps":9,"csat":5,"comment":"Great"}
レスポンス例
{"ok":true,"response":{"id":"SR-1001","date":"2026-07-22","cust":"Acme","src":"ticket","k":"CSAT","nps":9,"csat":5,"comment":"Great"}}
POST/api/survey/followup/:id公開
Record or replace a churn-save follow-up {action,note,date} for the response identified by :id.
パラメータ位置必須説明
idpathstringResponse id the follow-up is attached to (clip 60).
actionbodystringFollow-up action taken (clip 120), default ''.
notebodystringFollow-up note (clip 600), default ''.
datebodystringFollow-up date (clip 20), default ''.
リクエスト
{"action":"Called customer","note":"Resolved billing issue","date":"2026-07-22"}
レスポンス例
{"ok":true,"followup":{"action":"Called customer","note":"Resolved billing issue","date":"2026-07-22"}}

オンボーディング (Onboarding)

導入チェックリスト。

GET/api/onboarding/projects公開live 200
Returns the current onboarding projects state {sel,tab,projects} (7-step MDM/ABM flow per customer), self-seeding demo data if missing.
レスポンス例
{"ok":true,"state":{"sel":"北斗商事","tab":"cust","projects":{"北斗商事":{"mdm":"Intune","steps":{"kickoff":"done","abm":"done","apns":"done","design":"done","pilot":"done","rollout":"done","handover":"wip"},"start":"2026-06-27"},"三峰精機":{...},"科研製薬":{...}}}}
PUT/api/onboarding/projects公開
Replaces the projects state; requires a projects object, sanitizes sel (clip 120) and tab (emp|cust).
パラメータ位置必須説明
selbodystringselected customer key, clipped to 120 chars
tabbodystringactive tab; coerced to 'emp' if === 'emp' else 'cust'
projectsbodyobjectmap of customer -> {mdm,steps,start}; missing/non-object -> 400
リクエスト
{"sel":"北斗商事","tab":"cust","projects":{"北斗商事":{"mdm":"Intune","steps":{...},"start":"2026-06-27"}}}
レスポンス例
{"ok":true,"state":{"sel":"...","tab":"cust","projects":{...}}}
GET/api/onboarding/requests公開live 200
Lists all employee device requests, sorted ascending by ts. Seed is empty (mirrors client).
レスポンス例
{"ok":true,"requests":[]}
POST/api/onboarding/request公開
Creates a pending device request; honors a client-provided id so ids stay in sync. Requires name and dept.
パラメータ位置必須説明
idbodystringoptional client id, clipped 60; defaults to generated id('REQ')
namebodystringemployee name, clip 120; empty -> 400
deptbodystringdepartment, clip 120; empty -> 400
modelbodystringdevice model, clip 120
mdmbodystringMDM platform, clip 60, default 'Intune'
usebodystringusage/purpose, clip 60
ticketbodystringticket ref, clip 60
tsbodynumbertimestamp; defaults to Date.now() if not a number
リクエスト
{"name":"山田太郎","dept":"営業部","model":"iPhone 15","mdm":"Intune","use":"field","ticket":"T-100"}
レスポンス例
{"ok":true,"request":{"id":"REQ-...","name":"山田太郎","dept":"営業部","model":"iPhone 15","mdm":"Intune","use":"field","ticket":"T-100","status":"pending","ts":1700000000000}}
POST/api/onboarding/request/:id公開
Approve/reject/reset an existing request by id via {status}; on 'approved' sets a lead-time (optional lead days else random 0.8-2.4).
パラメータ位置必須説明
idpathstringrequest id; unknown -> 404 {error:'request not found'}
statusbodystringone of approved|rejected|pending; else 400 {error:'invalid status'}
leadbodynumberlead days when approving; if not a number, random 0.8-2.4 rounded to 1dp
リクエスト
{"status":"approved","lead":1.5}
レスポンス例
{"ok":true,"request":{"id":"REQ-...","status":"approved","lead":1.5,...}}

チーム (Team)

メンバー・権限・稼働。

GET/api/team/members公開live 200
Return the full list of team members from the team-members collection.
レスポンス例
{"ok":true,"members":[{"id":"t1","name":"佐藤 美咲","ini":"MS","role":"owner","dept":"経営","email":"misaki.sato@ai-sns.io"}, ...]}
POST/api/team/member公開
Create/invite a new member; server issues the id, requires a name.
パラメータ位置必須説明
namebodystringDisplay name; 400 if missing/blank; clipped to 80 chars.
inibodystringInitials, first 2 chars uppercased; defaults 'NA'.
rolebodystringOne of owner|admin|exec|member|viewer; defaults 'member'.
deptbodystringDepartment, clipped to 60; defaults '—'.
emailbodystringEmail, clipped to 120.
scopesbodyobjectPer-area perms {mgmt,ops,sales,support,settings} each none|view|edit.
リクエスト
{"name":"string","ini":"string?","role":"owner|admin|exec|member|viewer?","dept":"string?","email":"string?","scopes":{...}?}
レスポンス例
{"ok":true,"member":{"id":"t<generated>","name":"...","ini":"NA","role":"member","dept":"—","email":""}}
POST/api/team/member/:id公開
Update an existing member's role/scopes/fields; blocks demoting the last owner.
パラメータ位置必須説明
idpathstringMember id to update (e.g. 't5'); clipped to 40 chars.
rolebodystringNew role; blocked with 409 if demoting the last owner.
namebodystringUpdated name.
inibodystringUpdated initials.
deptbodystringUpdated department.
emailbodystringUpdated email.
scopesbodyobjectUpdated per-area scopes.
リクエスト
{"role":"...?","name":"...?","ini":"...?","dept":"...?","email":"...?","scopes":{...}?}
レスポンス例
{"ok":true,"member":{"id":"t5","name":"中村 由美","role":"member", ...}}
POST/api/team/member/:id/delete公開
Delete a member by id; refuses to remove the last remaining owner.
パラメータ位置必須説明
idpathstringMember id to delete (e.g. 't6'); clipped to 40 chars.
レスポンス例
{"ok":true,"id":"t6"}
GET/api/team/plan公開live 200
Return the current billing plan key (starter|pro|ent), defaulting to 'pro'.
レスポンス例
{"ok":true,"planKey":"pro"}
POST/api/team/plan公開
Set the current billing plan; validates against starter|pro|ent.
パラメータ位置必須説明
planKeybodystringTarget plan; must be one of starter|pro|ent, else 400; clipped to 20 chars.
リクエスト
{"planKey":"starter|pro|ent"}
レスポンス例
{"ok":true,"planKey":"pro"}

設定 (Settings)

テナント設定・機能フラグ。

GET/api/settings/company公開live 200
Return the issuer/company profile stamped onto quote/invoice/certificate PDFs.
レスポンス例
{"ok":true,"company":{"name":"株式会社 ai-sns.io","brand":"ai-sns.io Kitting","addr":"東京都板橋区・板橋キッティングセンター","tel":"","email":"","regno":"","rep":"","web":"","bank":"","logo":""}}
PUT/api/settings/company公開
Merge-update the issuer/company profile (text fields + base64 logo dataURL).
パラメータ位置必須説明
namebodystringCompany legal name (clipped to 300 chars)
brandbodystringBrand/product name (clip 300)
addrbodystringAddress (clip 300)
telbodystringPhone (clip 300)
emailbodystringContact email (clip 300)
regnobodystringRegistration/invoice number (clip 300)
repbodystringRepresentative name (clip 300)
webbodystringWebsite URL (clip 300)
bankbodystringBank details (clip 300)
logobodystringLogo base64 dataURL (clipped to 6MB)
リクエスト
{"name":"...","brand":"...","addr":"...","tel":"...","email":"...","regno":"...","rep":"...","web":"...","bank":"...","logo":"data:image/png;base64,..."}
レスポンス例
{"ok":true,"company":{...merged record...}}
GET/api/settings/prefs公開live 200
Return notification preferences (emailNotify / slaAlert toggles).
レスポンス例
{"ok":true,"prefs":{"emailNotify":true,"slaAlert":true}}
PUT/api/settings/prefs公開
Merge-update notification toggles (emailNotify / slaAlert).
パラメータ位置必須説明
emailNotifybodybooleanEmail notification toggle; coerced with !! (default true)
slaAlertbodybooleanSLA breach alert toggle; coerced with !! (default true)
リクエスト
{"emailNotify":true,"slaAlert":false}
レスポンス例
{"ok":true,"prefs":{"emailNotify":true,"slaAlert":false}}

連携 (Integrations)

Teams / Slack / LINE WORKS 等。

GET/api/integrations/rules公開live 200
Returns the automation rule toggles (trigger->action) plus any user-added extra rules.
レスポンス例
{"ok":true,"rules":{"r-ship":true,"r-inv":true,"r-lost":true,"r-ade":true,"r-sla":true,"r-pay":false},"extraRules":[]}
PUT/api/integrations/rules公開
Persists the whole rules state; replaces rules map (id->bool) and/or the extraRules array.
パラメータ位置必須説明
rulesbodyobjectMap of ruleId->boolean; keys clipped to 60 chars, values coerced to bool. Must be an object (else 400).
extraRulesbodyarrayArray of rule objects {id,trig,act,ic,on}; normalized/clipped per-field. Must be an array (else 400).
リクエスト
{"rules":{"r-ship":true,"r-pay":true},"extraRules":[{"id":"r-x1","trig":"...","act":"...","ic":"⚙️","on":true}]}
レスポンス例
{"ok":true,"rules":{...},"extraRules":[...]}
GET/api/integrations/log公開live 200
Returns the recent sync log entries, newest first (sorted by time desc).
レスポンス例
{"ok":true,"log":[{"id":"LOG-0001","service":"intune","kind":"インベントリ取得","result":"ok","time":"2026-07-21T22:06:57.616Z"}]}
POST/api/integrations/log公開
Appends a new sync-log entry and returns it plus the full (bounded to 60) log.
パラメータ位置必須説明
servicebodystringService name, clipped to 60 chars and trimmed; required (else 400).
kindbodystringDescription of the sync action, clipped to 200 chars.
resultbodystringOne of ok|warn|err; anything else defaults to 'ok'.
timebodystringISO timestamp clipped to 40 chars; defaults to now.
リクエスト
{"service":"yamato","kind":"送り状 発行","result":"ok","time":"2026-07-22T00:00:00.000Z"}
レスポンス例
{"ok":true,"entry":{"id":"LOG-0008","service":"yamato","kind":"送り状 発行","result":"ok","time":"..."},"log":[...]}

コンプライアンス (Compliance)

ISMS/Pマーク/SOC2/APPI・監査ログ・CAPA。

GET/api/compliance公開live 200
Returns control checklists per standard (isms/pmark/soc2/appi) plus the full CAPA corrective-action list.
レスポンス例
{"ok":true,"controls":{"isms":[true,true,true,true,false,true],"pmark":[...],"soc2":[...],"appi":[...]},"capa":[{"id":"CAPA-2026-014","src":"SOC 2","finding":"変更管理の承認記録に一部欠落","due":"2026-07-25","owner":"佐々木 玲","state":"対応中"}]}
POST/api/compliance/capa/:id公開
Updates the state of a single corrective action (CAPA) identified by id.
パラメータ位置必須説明
idpathstringCAPA id, e.g. CAPA-2026-014
statebodystringNew state string, clipped to 20 chars; must be non-empty after trim
リクエスト
{"state":"是正待ち"}
レスポンス例
{"ok":true,"capa":{"id":"CAPA-2026-014","src":"SOC 2","finding":"...","due":"2026-07-25","owner":"佐々木 玲","state":"是正待ち"}}
PUT/api/compliance/controls/:key公開
Replaces a standard's control checklist with a new boolean array.
パラメータ位置必須説明
keypathstringControl set key: isms | pmark | soc2 | appi
controlsbodyboolean[]Array of booleans (coerced via !!), first 100 kept
リクエスト
{"controls":[true,true,false,true,false,true]}
レスポンス例
{"ok":true,"key":"isms","controls":[true,true,false,true,false,true]}
GET/api/audit-log公開live 200
Returns the tamper-evident audit trail as newest-first rows, each [ts,user,action,target,result,cat].
レスポンス例
{"ok":true,"logs":[["2026-07-11 09:02","佐々木 玲","ログイン(多要素認証)","管制コンソール","成功","login"],["2026-07-11 09:14","田中 亮","端末台帳 更新(ステータス変更)","IMEI 356821…4471","成功","ledger"]]}
POST/api/audit-log公開
Appends a new audit entry; auto-fills ts/user/target/result/cat defaults when omitted.
パラメータ位置必須説明
actionbodystringAction description, clipped 200, must be non-empty after trim
tsbodystringTimestamp, clipped 25; defaults to server now() 'YYYY-MM-DD HH:mm'
userbodystringActor, clipped 60; defaults to 'システム'
targetbodystringTarget, clipped 200; defaults to '—'
resultbodystringResult, clipped 20; defaults to '成功'
catbodystringCategory, clipped 20; defaults to 'audit'
リクエスト
{"action":"消去実行","user":"山本 佳奈","target":"北斗商事 45台","result":"成功","cat":"erase"}
レスポンス例
{"ok":true,"entry":["2026-07-22 10:15","山本 佳奈","消去実行","北斗商事 45台","成功","erase"]}

ワークデスク (Workdesk)

社内ナレッジ・依頼。

GET/api/workdesk/docs公開live 200
List source-library documents, newest user-added first then seed docs in original order.
レスポンス例
{"ok":true,"docs":[{"id":"sop","name":"キッティング手順書","type":"SOP","size":184320,"status":"索引済","date":"2026/07/21","created":0,"seedIdx":0}]}
POST/api/workdesk/doc公開
Create/upsert a document; all body fields optional, defaults applied.
パラメータ位置必須説明
idbodystringDoc id (clip 60); auto-generated 'doc-...' if omitted
namebodystringDoc name (clip 200); defaults '資料-<timestamp>'
typebodystringDoc type (clip 40); defaults 'FILE'
sizebodynumberByte size; defaults 0
statusbodystringIndex status (clip 40); defaults '索引済'
datebodystringDisplay date (clip 40); defaults today() JA date
リクエスト
{"name":"...","type":"...","size":123,"status":"...","date":"...","id":"..."}
レスポンス例
{"ok":true,"doc":{"id":"doc-...","name":"...","type":"FILE","size":0,"status":"索引済","date":"2026/07/22","created":1700000000000}}
POST/api/workdesk/doc/:id/delete公開
Delete a document by id; 404 if not found.
パラメータ位置必須説明
idpathstringDoc id to delete (e.g. 'sop')
レスポンス例
{"ok":true}
GET/api/workdesk/threads公開live 200
List AI chat threads, newest first (created desc); seed is empty.
レスポンス例
{"ok":true,"threads":[]}
POST/api/workdesk/thread公開
Create/upsert a full chat thread; body optional, sanitizes msgs.
パラメータ位置必須説明
idbodystringThread id (clip 60); auto-generated 'thr-...' if omitted
titlebodystringTitle (clip 120); defaults '新しいチャット'
tsbodystringTimestamp label (clip 40)
msgsbodyarrayMessages [{role,text?,html?,srcs?,typing?}], each sanitized via cleanMsg
リクエスト
{"id":"...","title":"...","ts":"...","msgs":[{"role":"user","text":"..."}]}
レスポンス例
{"ok":true,"thread":{"id":"thr-...","title":"新しいチャット","ts":"","msgs":[],"created":1700000000000}}
POST/api/workdesk/thread/:id公開
Append/replace msgs or rename a thread; creates thread on-append if missing.
パラメータ位置必須説明
idpathstringThread id
titlebodystringRename thread (clip 120)
tsbodystringTimestamp label (clip 40)
msgsbodyarrayReplace whole msgs list
appendbodyarrayAppend msgs to existing list
リクエスト
{"title":"...","ts":"...","msgs":[...],"append":[{"role":"ai","text":"..."}]}
レスポンス例
{"ok":true,"thread":{"id":"...","title":"...","ts":"...","msgs":[...],"created":1700000000000}}
POST/api/workdesk/conn公開
Persist connector on/off map {id:bool,...}, coerced to booleans.
パラメータ位置必須説明
mapbodyobject{id:bool} map; body itself used as map if no .map key. Keys clip 40, values coerced !!
リクエスト
{"slack":true,"teams":false}  OR  {"map":{"slack":true}}
レスポンス例
{"ok":true,"conn":{"slack":true,"teams":false}}
GET/api/workdesk/conn公開live 200
Read persisted connector on/off map (hydration convenience).
レスポンス例
{"ok":true,"conn":{}}

ESG

リユース・CO2・サステナビリティ指標。

GET/api/esg/settings公開live 200
Return the auditable ESG coefficients (co2e kg-CO2e/unit, ewaste kg/unit).
レスポンス例
{"ok":true,"settings":{"co2e":55,"ewaste":0.42}}
PUT/api/esg/settings公開
Merge-update the ESG coefficients; accepts positive finite co2e and/or ewaste, else keeps prior value.
パラメータ位置必須説明
co2ebodynumberkg-CO2e per unit; only applied when a positive finite number, otherwise previous value kept
ewastebodynumberkg per unit; only applied when a positive finite number, otherwise previous value kept
リクエスト
{"co2e": 55, "ewaste": 0.42}
レスポンス例
{"ok":true,"settings":{"co2e":60,"ewaste":0.5}}
GET/api/esg/metrics公開live 200
Return FY, monthly reuse volumes, per-customer reuse/return figures, and aggregate totals (reuse, ret, circularity %).
レスポンス例
{"ok":true,"fy":"2026年度","months":["4","5",...],"monthly":[78,85,...],"customers":[{"name":"北斗商事","reuse":420,"ret":470},...],"totals":{"reuse":1240,"ret":1420,"circularity":87.3}}

顧客ポータル (Portal)

顧客共有ビュー。

GET/api/portals公開live 200
Returns the full customer portal state: per-customer {published,suffix,last,name,slug} plus global counters _tickets (MTD) and _dls (avg monthly downloads).
レスポンス例
{"ok":true,"state":{"hokuto":{"published":true,"suffix":"blk3","last":"3分前","name":"北斗商事","slug":"hokuto"},"tosei":{"published":false,"suffix":"1jip","last":"—",...},"_tickets":4,"_dls":63}}
POST/api/portal/:custId公開
Mutates one customer portal. body.action: 'toggle' (default; flip or set published, sets last='たった今' when publishing) | 'ticket' (bump global tickets, set last) | 'dl' (bump global downloads) | 'touch' (set last from body.last). Returns updated portal + counters.
パラメータ位置必須説明
custIdpathstringCustomer id: one of hokuto|mitsumine|kaken|tosei|mizuki. 404 if unknown.
actionbodystringOne of toggle|ticket|dl|touch (default toggle, clipped to 20 chars). Unknown value -> 400.
publishedbodybooleanFor action=toggle: explicit publish state; if omitted, flips current value.
lastbodystringFor action=touch: last-access label, clipped to 40 chars (default 'たった今').
リクエスト
{"action":"toggle","published":true,"last":"たった今"}
レスポンス例
{"ok":true,"portal":{"id":"tosei","name":"東成建設","slug":"tosei","published":true,"suffix":"1jip","last":"たった今"},"tickets":4,"dls":63}
POST/api/portal/issue公開
Issues (publishes) a portal for a customer identified by body.custId/id, sets published=true and last='たった今', and returns the public portal URL '/portal.html?c=<name>'.
パラメータ位置必須説明
custIdbodystringCustomer id (alias 'id' also accepted), clipped to 40 chars; must map to a known customer else 400.
リクエスト
{"custId":"tosei"}
レスポンス例
{"ok":true,"url":"/portal.html?c=%E6%9D%B1%E6%88%90%E5%BB%BA%E8%A8%AD","portal":{"id":"tosei","name":"東成建設","slug":"tosei","published":true,"suffix":"1jip","last":"たった今"}}

QBR

四半期ビジネスレビュー。

GET/api/qbr/history公開live 200
List generated-QBR history entries (newest-first, capped at 20).
レスポンス例
{"ok":true,"history":[]}
POST/api/qbr公開
Record a generated QBR into history; returns the new record plus updated capped history.
パラメータ位置必須説明
custIdbodystringCustomer id (clipped to 60 chars); required, 400 if missing.
qIdbodystringQuarter id (clipped to 40 chars); required, 400 if missing.
custbodystringCustomer display name (clipped to 120 chars).
qbodystringQuarter label (clipped to 60 chars).
datebodystringISO date string (clipped to 40 chars); defaults to current ISO timestamp if omitted.
リクエスト
{"custId":"c1","cust":"Acme","qId":"2026Q2","q":"2026 Q2","date":"2026-07-22T00:00:00.000Z"}
レスポンス例
{"ok":true,"record":{"custId":"c1","cust":"Acme","qId":"2026Q2","q":"2026 Q2","date":"2026-07-22T00:00:00.000Z"},"history":[{...}]}

ナーチャリング (Nurture)

リード育成・シーケンス。

GET/api/nurture公開live 200
Return the single nurture config+history doc (per-step edits, custom drip sequences, send-history flags, auto-remind toggle).
レスポンス例
{"ok":true,"doc":{"edits":{},"custom":[],"sent":{},"autoRemind":true}}
POST/api/nurture公開
Persist (replace) the nurture config+history doc after shaping/clipping to bounded sizes.
パラメータ位置必須説明
editsbodyobjectPer-step overrides map keyed 'seqId:idx' -> {subject(<=300), body(<=8000)}; capped 500 keys.
custombodyarrayUser drip sequences [{id,name,target,tone,desc,steps:[{day,subject,body}]}]; capped 100 seqs, 40 steps each.
sentbodyobjectSend-history flags map 'leadId:seqId:idx' -> true; capped 5000 keys.
autoRemindbodybooleanAuto renewal-reminder toggle; defaults true when null/omitted.
リクエスト
{ "edits": { "seqId:0": {"subject":"...","body":"..."} }, "custom": [ {"id":"...","name":"...","target":"...","tone":"...","desc":"...","steps":[{"day":0,"subject":"...","body":"..."}]} ], "sent": {"leadId:seqId:0":true}, "autoRemind": true }
レスポンス例
{"ok":true,"doc":{"edits":{},"custom":[],"sent":{},"autoRemind":true}}

管理者 (Admin)

主管理者認証・テナント管理・サブ管理者CRUD。要adminトークン

POST/api/admin/login公開
Master-admin login; returns an 8h HMAC-signed bearer token when the password matches ADMIN_PASSWORD.
パラメータ位置必須説明
passwordbodystringMaster admin password (env ADMIN_PASSWORD, default 'kitting-admin')
リクエスト
{"password":"kitting-admin"}
レスポンス例
{"ok":true,"token":"<body>.<sig>"} | 401 {"ok":false,"error":"パスワードが違います"}
GET/api/admin/tenantsadminlive 401
List all tenants plus aggregate stats (totals, active/trial/suspended counts, MRR, devices, seats, sites, clients).
パラメータ位置必須説明
tokenquerystringAdmin token (alternative to Authorization: Bearer header)
レスポンス例
{"ok":true,"tenants":[{"id":"t-itabashi","name":"板橋キッティングセンター","plan":"Business","seats":180,"used":120,"status":"active","mrr":582000,"devices":1204,"clients":[...],"features":{...}}],"stats":{"total":5,"active":3,"trial":1,"suspended":1,"mrr":2487000,...},"origin":"https://..."}
GET/api/admin/tenant/:idadminlive 401
Get one tenant with derived client dashboard URLs and published-site URLs.
パラメータ位置必須説明
idpathstringTenant id, e.g. t-itabashi
tokenquerystringAdmin token (alt to Bearer header)
レスポンス例
{"ok":true,"tenant":{...},"dashboards":[{"client":"北斗商事","url":".../portal.html?c=..."}],"published":[{"slug":"itabashi-kitting","url":".../site/itabashi-kitting","live":true}],"origin":"https://..."}
POST/api/admin/tenant/:idadmin
Update an existing tenant's editable fields (name, plan, seats, used, status, email, devices, mrr, features, clients).
パラメータ位置必須説明
idpathstringTenant id to update
namebodystringTenant display name
planbodystringStarter|Business|Enterprise
seatsbodynumberLicensed seats
usedbodynumberSeats used
statusbodystringactive|trial|suspended
emailbodystringContact email
devicesbodynumberManaged device count
mrrbodynumberMonthly recurring revenue
featuresbodyobjectFeature-flag object merged into existing
clientsbodyarrayClient name array (capped at 200)
リクエスト
{"plan":"Enterprise","seats":300,"status":"active","features":{"daas":true}}
レスポンス例
{"ok":true,"tenant":{...updated...}}
POST/api/admin/tenantadmin
Create a new tenant (auto-generated id 't-<slug>-<hex>'), defaults to Starter/trial with base feature flags.
パラメータ位置必須説明
namebodystringTenant name (default '新規テナント', 80-char cap)
planbodystringPlan (default Starter)
seatsbodynumberSeats (default 3)
emailbodystringContact email
リクエスト
{"name":"新規センター","plan":"Business","seats":50,"email":"x@example.jp"}
レスポンス例
{"ok":true,"tenant":{"id":"t-...-a1b2","status":"trial","used":0,"mrr":0,"features":{...}}}
POST/api/admin/tenant/:id/deleteadmin
Delete a tenant from the store and persist.
パラメータ位置必須説明
idpathstringTenant id to delete
レスポンス例
{"ok":true}
POST/api/admin/tenant/:id/clientadmin
Add a client name to a tenant and return that client's portal dashboard URL.
パラメータ位置必須説明
idpathstringTenant id
clientbodystringClient name (80-char cap; 400 if empty)
リクエスト
{"client":"新規クライアント"}
レスポンス例
{"ok":true,"url":".../portal.html?c=%E6%96%B0%E8%A6%8F..."}
POST/api/admin/impersonate/:idadmin
Return an assist-mode ('admin_as') app URL for the given tenant (app shows a disclaimer banner).
パラメータ位置必須説明
idpathstringTenant id to impersonate
レスポンス例
{"ok":true,"url":".../app?admin_as=%E6%9D%BF%E6%A9%8B..."}
GET/api/admin/subadminsadminlive 401
List all sub-admins (public-safe fields, no passwords) plus a compact {id,name} tenant list for assignment.
パラメータ位置必須説明
tokenquerystringAdmin token (alt to Bearer header)
レスポンス例
{"ok":true,"subadmins":[{"id":"sa-demo","name":"サポート担当 山田","email":"yamada@ai-sns.io","tenants":["t-itabashi","t-nagoya"],"perms":{"canDelete":true},"active":true,"created":"2026-06-01"}],"tenants":[{"id":"t-itabashi","name":"板橋キッティングセンター"}]}
POST/api/admin/subadminadmin
Create a sub-admin; validates required name/email and unique email, auto-generates a password if none supplied.
パラメータ位置必須説明
namebodystringSub-admin name (80-char cap)
emailbodystringUnique email
passwordbodystringLogin password (random hex if omitted)
tenantsbodyarrayAssigned tenant ids (cap 200)
canDeletebodybooleanGrant delete permission
リクエスト
{"name":"新担当","email":"new@ai-sns.io","tenants":["t-osaka"],"canDelete":false}
レスポンス例
{"ok":true,"subadmin":{...},"password":"<pass>"}
POST/api/admin/subadmin/:idadmin
Update a sub-admin's name, email, password, assigned tenants, canDelete perm, or active flag.
パラメータ位置必須説明
idpathstringSub-admin id
namebodystringNew name
emailbodystringNew email
passwordbodystringNew password
tenantsbodyarrayReassign tenant ids
canDeletebodybooleanToggle delete perm
activebodybooleanEnable/disable account
リクエスト
{"active":false,"canDelete":true}
レスポンス例
{"ok":true,"subadmin":{...updated...}}
POST/api/admin/subadmin/:id/deleteadmin
Delete a sub-admin and persist.
パラメータ位置必須説明
idpathstringSub-admin id to delete
レスポンス例
{"ok":true}
GET/api/admin/backupsadminlive 401
Return the global backup log (up to 120 newest snapshots across all tenants) plus daily-backup status.
パラメータ位置必須説明
tokenquerystringAdmin token (alt to Bearer header)
レスポンス例
{"ok":true,"log":[{"tenantId":"t-itabashi","tenantName":"板橋キッティングセンター","id":"bk-...","ts":1699999999999,"by":"system","reason":"日次自動バックアップ","sites":1}],"daily":{"last":1699999999999,"tenants":5}}
GET/api/admin/activityadminlive 401
Return the audit/activity log (newest first, up to 200 entries).
パラメータ位置必須説明
tokenquerystringAdmin token (alt to Bearer header)
レスポンス例
{"ok":true,"activity":[{"ts":1699999999999,"by":"サポート担当 山田","role":"subadmin","action":"パスワードを変更","tenantId":"","tenantName":"","detail":""}]}

サブ管理者 (Sub-Admin)

担当クライアント限定の運用(メモ・ファイル・削除)。要subadminトークン

POST/api/subadmin/login公開
Sub-admin login; matches email+password against the subadmins map and issues an 8h HMAC token.
パラメータ位置必須説明
emailbodystringSub-admin email, lowercased/trimmed before match (seed: yamada@ai-sns.io)
passwordbodystringPlaintext password; seed default 'kitting-sub' (or SUBADMIN_PASSWORD env)
リクエスト
{"email":"yamada@ai-sns.io","password":"kitting-sub"}
レスポンス例
{"ok":true,"token":"<b64>.<sig>","sub":{"id":"sa-demo","name":"サポート担当 山田","email":"yamada@ai-sns.io","tenants":["t-itabashi","t-nagoya"],"perms":{"canDelete":true},"active":true,"created":"2026-06-01"}}
GET/api/subadmin/mesubadminlive 401
Returns the authenticated sub-admin profile, their in-scope tenants, and aggregate stats.
パラメータ位置必須説明
tokenquerystringAlternative to Authorization: Bearer header
レスポンス例
{"ok":true,"sub":{...},"tenants":[{"id":"t-itabashi",...}],"stats":{"tenants":2,"devices":1414,"clients":5,"sites":1},"origin":"https://aisnsio-kitting.hf.space"}
GET/api/subadmin/tenant/:idsubadminlive 401
Scoped read of one tenant plus derived dashboards, published sites, backups, and the sub-admin's perms.
パラメータ位置必須説明
idpathstringTenant id, must be in sub-admin scope (seed: t-itabashi, t-nagoya)
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"tenant":{"id":"t-itabashi","clients":["北斗商事",...],"sites":["itabashi-kitting"]},"dashboards":[{"client":"北斗商事","url":".../portal.html?c=..."}],"published":[{"slug":"itabashi-kitting","url":".../site/itabashi-kitting","live":true}],"backups":[],"perms":{"canDelete":true},"origin":"..."}
POST/api/subadmin/tenant/:idsubadmin
Scoped non-core tenant edit; only the contact email can be changed, main settings are blocked.
パラメータ位置必須説明
idpathstringTenant id, must be in scope
emailbodystringNew contact email (max 120 chars)
plan/seats/mrr/status/featuresbodyanyIf any present -> 403; sub-admins may not change core settings
リクエスト
{"email":"new@example.co.jp"}
レスポンス例
{"ok":true,"tenant":{"id":"t-itabashi","email":"new@example.co.jp",...}}
POST/api/subadmin/tenant/:id/clientsubadmin
Adds a client name to a scoped tenant and returns its portal URL.
パラメータ位置必須説明
idpathstringTenant id, must be in scope
clientbodystringClient name (max 80 chars); 400 if empty
リクエスト
{"client":"新規クライアント"}
レスポンス例
{"ok":true,"url":"https://aisnsio-kitting.hf.space/portal.html?c=%E6%96%B0%E8%A6%8F..."}
POST/api/subadmin/impersonate/:idsubadmin
Generates an assisted-login URL into the client app for a scoped tenant (support impersonation).
パラメータ位置必須説明
idpathstringTenant id, must be in scope
レスポンス例
{"ok":true,"url":"https://aisnsio-kitting.hf.space/app?admin_as=%E6%9D%BF%E6%A9%8B...&by=subadmin"}
POST/api/subadmin/delete-requestsubadmin
Requests deletion of a client/site/tenant; generates a 6-digit access code (10-min expiry) gated by canDelete perm.
パラメータ位置必須説明
tenantIdbodystringTenant id, must be in scope
targetTypebodystring'client'|'site'|'tenant', defaults to 'client'
targetIdbodystringId/name of the thing to delete (max 120)
リクエスト
{"tenantId":"t-itabashi","targetType":"client","targetId":"北斗商事"}
レスポンス例
{"ok":true,"requestId":"dr-<hex>","sentTo":["itabashi@example.co.jp","マスター管理者"],"expiresInMin":10,"demoCode":"123456"}
POST/api/subadmin/delete-confirmsubadmin
Confirms a delete request with the emailed access code and performs the scoped delete after auto-backup.
パラメータ位置必須説明
requestIdbodystringId from delete-request; must belong to this sub-admin
codebodystring6-digit access code
リクエスト
{"requestId":"dr-<hex>","code":"123456"}
レスポンス例
{"ok":true,"targetType":"client"}
GET/api/subadmin/activitysubadminlive 401
Returns up to 150 recent activity-log entries filtered to the sub-admin's own actions or in-scope tenants.
パラメータ位置必須説明
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"activity":[{"ts":1700000000000,"by":"サポート担当 山田","role":"subadmin","action":"サポートメモを追加","tenantId":"t-itabashi","tenantName":"板橋キッティングセンター","detail":"..."}]}
GET/api/subadmin/backups-allsubadminlive 401
Aggregated backup log across all of the sub-admin's tenants, newest first, capped at 120 rows.
パラメータ位置必須説明
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"log":[{"tenantId":"t-itabashi","tenantName":"板橋キッティングセンター","id":"bk-...","ts":1700000000000,"reason":"...","by":"..."}]}
POST/api/subadmin/passwordsubadmin
Self-service password change for the authenticated sub-admin.
パラメータ位置必須説明
currentbodystringCurrent password; 401 if wrong (plaintext compare)
nextbodystringNew password, min 6 chars else 400
リクエスト
{"current":"kitting-sub","next":"newpass123"}
レスポンス例
{"ok":true}
GET/api/notes/:tenantIdsubadminlive 401
Lists support notes for a tenant (admin any tenant, sub-admin scoped).
パラメータ位置必須説明
tenantIdpathstringTenant id; sub-admin must have it in scope (seed: t-itabashi)
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"notes":[{"id":"nt-...","ts":1700000000000,"by":"サポート担当 山田","text":"...","done":false}]}
POST/api/notes/:tenantIdsubadmin
Adds a support note (max 600 chars) to a tenant's note list.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped for sub-admin
textbodystringNote text, trimmed, max 600; 400 if empty
リクエスト
{"text":"クライアントへ連絡済み"}
レスポンス例
{"ok":true,"note":{"id":"nt-...","ts":1700000000000,"by":"サポート担当 山田","text":"...","done":false}}
POST/api/notes/:tenantId/:noteIdsubadmin
Updates (text/done) or deletes a specific support note.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped
noteIdpathstringNote id (nt-...)
delbodybooleanIf truthy, delete the note and return {ok:true}
donebodybooleanToggle done flag
textbodystringNew text (max 600)
リクエスト
{"done":true}
レスポンス例
{"ok":true,"note":{"id":"nt-...","done":true,"text":"..."}}
GET/api/files/:tenantIdsubadminlive 401
Lists uploaded file metadata (no data blob) for a tenant.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped (seed: t-itabashi)
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"files":[{"id":"fl-...","ts":1700000000000,"by":"サポート担当 山田","name":"手順書.pdf","type":"application/pdf","size":10240}]}
POST/api/files/:tenantIdsubadmin
Uploads a base64 file/document (up to ~2MB) attached to a tenant.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped
namebodystringFile name (max 160), defaults 'file'
typebodystringMIME type (max 80)
databodystringBase64/data payload; 400 if empty, 413 if >2,800,000 chars
sizebodynumberReported size; defaults to data.length
リクエスト
{"name":"doc.pdf","type":"application/pdf","data":"<base64>"}
レスポンス例
{"ok":true,"file":{"id":"fl-...","ts":1700000000000,"by":"...","name":"doc.pdf","type":"application/pdf","size":12345}}
GET/api/files/:tenantId/:fileId/downloadsubadminlive 401
Returns a single file's full base64 data for download.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped
fileIdpathstringFile id (fl-...); 404 if not found
tokenquerystringAlternative to Bearer header
レスポンス例
{"ok":true,"name":"doc.pdf","type":"application/pdf","data":"<base64>"}
POST/api/files/:tenantId/:fileId/deletesubadmin
Deletes an uploaded file from a tenant's file list.
パラメータ位置必須説明
tenantIdpathstringTenant id, scoped
fileIdpathstringFile id to remove
レスポンス例
{"ok":true}

バックアップ (Backup/Export)

日次バックアップ・状態エクスポート。要BACKUP_TOKEN

GET/api/admin/backupsadminlive 401
Master-admin global backup log (last 120 snapshot rows across all tenants) plus daily auto-backup status.
パラメータ位置必須説明
tokenquerystringAdmin JWT; alternatively sent as Authorization: Bearer <token>. Required.
レスポンス例
{"ok":true,"log":[{"tenantId":"t-itabashi","tenantName":"板橋キッティングセンター","id":"bk-...","ts":1784600000000,"by":"system","reason":"日次自動バックアップ","sites":1}],"daily":{"last":1784600000000,"tenants":5}}
GET/api/backups/:tenantIdadminlive 401
List backup snapshot metadata for one tenant (newest first), for admin or the scoped sub-admin.
パラメータ位置必須説明
tenantIdpathstringTenant id, e.g. t-itabashi (seed tenants: t-itabashi, t-osaka, t-nagoya, t-fukuoka, t-sapporo).
tokenquerystringAdmin or sub-admin JWT; also accepted as Authorization: Bearer. Required.
レスポンス例
{"ok":true,"backups":[{"id":"bk-lz...","ts":1784600000000,"by":"system","reason":"日次自動バックアップ","sites":1}]}
GET/api/subadmin/backups-allsubadminlive 401
Scope-wide backup log for the logged-in sub-admin: last 120 snapshot rows across only their assigned tenants.
パラメータ位置必須説明
tokenquerystringSub-admin JWT (role==='subadmin'); also accepted as Authorization: Bearer. Required.
レスポンス例
{"ok":true,"log":[{"tenantId":"t-nagoya","tenantName":"名古屋モバイル管理","id":"bk-...","ts":1784600000000,"by":"system","reason":"日次自動バックアップ","sites":0}]}
GET/api/export/statetokenlive 200
Full runtime-data dump (all tenants/sites/subadmins/backups/leads/signs/bookings/etc. + counts) for automated off-site backups.
パラメータ位置必須説明
tokenquerystringBackup token; must equal env BACKUP_TOKEN (default 'kitting-backup-token'). Alternatively header x-backup-token. Required (one of the two).
レスポンス例
{"ok":true,"exportedAt":1784675572317,"space":"Aisnsio/kitting","tenants":{"t-itabashi":{...}},"sites":{...},"backups":{...},"counts":{"tenants":5,"backups":5,...}}
POST/api/backup/:tenantIdadmin
Create an on-demand snapshot of one tenant (deep-copies tenant record + its sites) with an optional reason label.
パラメータ位置必須説明
tenantIdpathstringTenant id to snapshot, e.g. t-itabashi.
tokenquerystringAdmin or scoped sub-admin JWT (or Authorization: Bearer). Required.
reasonbodystringBackup reason/label, sliced to 120 chars; defaults to '手動バックアップ'.
リクエスト
{"reason":"設定変更前の手動バックアップ"}
レスポンス例
{"ok":true,"backup":{"id":"bk-lz9x...","ts":1784675000000,"by":"マスター管理者","reason":"手動バックアップ","sites":1}}
POST/api/restore/:tenantId/:backupIdadmin
Rollback: restore a tenant (and its sites) from a stored snapshot; auto-snapshots current state first for recoverability.
パラメータ位置必須説明
tenantIdpathstringTenant id to roll back, e.g. t-itabashi.
backupIdpathstringSnapshot id to restore, e.g. bk-lz9x2a (obtained from GET /api/backups/:tenantId).
tokenquerystringAdmin or scoped sub-admin JWT (or Authorization: Bearer). Required.
レスポンス例
{"ok":true,"tenant":{"id":"t-itabashi","name":"板橋キッティングセンター","plan":"Business","sites":["itabashi-kitting"],...}}

公開フォーム・OAuth・その他 (Misc)

申込/パートナー/予約/署名/CRM・OAuth連携。

POST/api/synthia公開
Synthia AI chat proxy: forwards message+history to Anthropic Claude if ANTHROPIC_API_KEY is set, else returns a fallback flag so the client uses its built-in mock.
パラメータ位置必須説明
messagebodystringUser message (sliced to 4000 chars)
historybodyarrayPrior turns [{role:'user'|'assistant',content}], last 8 used
リクエスト
{"message":"string","history":[{"role":"user","content":"..."}]}
レスポンス例
{"ok":false,"fallback":true,"reason":"no_key"} | {"ok":true,"text":"...","model":"claude-opus-4-8"}
GET/api/marketprice公開live 200
Live used-device market-price lookup for trade-in/buyback via SerpAPI / Yahoo Shopping / Google CSE; returns reference note if no key configured.
パラメータ位置必須説明
modelquerystringDevice model keyword (<=80 chars); 400 if missing
condquerystringCondition keyword (<=24 chars)
レスポンス例
{"ok":true,"live":false,"model":"iPhone 13","note":"ライブ相場APIキーが未設定です…"}
GET/api/connect/status公開live 200
Lists all 13 integration providers (MDM/Apple/shipping/accounting/chat) with connected state, configured flag, redirectUri and go-live guide.
レスポンス例
{"ok":true,"origin":"https://aisnsio-kitting.hf.space","providers":[{"key":"intune","name":"Microsoft Intune","group":"MDM","authType":"oauth","connected":false,"configured":false,"guide":{...}}]}
GET/api/connect/:provider公開live 200
Starts OAuth: redirects (302) to the provider authorize URL for oauth providers, or returns an HTML popup for credential providers / unset creds.
パラメータ位置必須説明
providerpathstringProvider key e.g. intune, freee, moneyforward, lineworks
レスポンス例
HTTP 200 text/html popup, OR 302 redirect to authorize URL, OR 404 text 'unknown provider'
GET/api/connect/:provider/callback公開live 200
OAuth redirect callback: validates state, exchanges the code for tokens against the provider, stores them, and returns an HTML popup that postMessages the opener.
パラメータ位置必須説明
providerpathstringProvider key
codequerystringOAuth authorization code
statequerystringCSRF state from the authorize step
errorquerystringProvider error code
レスポンス例
HTTP 200 text/html popup ('接続に失敗しました' on state mismatch / '接続が完了しました' on success)
POST/api/connect/:provider/credentials公開
Saves API-key/token/webhook credentials for a credential-type provider; for webhook providers sends a real test POST to validate.
パラメータ位置必須説明
providerpathstringCredential provider key e.g. jamf, teams, yamato
fieldsbodyobjectMap of field key->value; all provider fields required
リクエスト
{"fields":{"webhook":"https://..."}}
レスポンス例
{"ok":true,"tested":true} | {"ok":false,"error":"...が未入力です"}
POST/api/connect/:provider/disconnect公開
Removes stored tokens/credentials for a provider.
パラメータ位置必須説明
providerpathstringProvider key
レスポンス例
{"ok":true}
POST/api/site/publish公開
Publishes a white-label tenant marketing site (slug+HTML) served at /site/<slug>.
パラメータ位置必須説明
slugbodystringa-z0-9- slug (<=40); 400 if empty after sanitize
htmlbodystringSite HTML (<=800000 chars)
namebodystringDisplay name (<=120)
リクエスト
{"slug":"acme","html":"<html>..","name":"Acme"}
レスポンス例
{"ok":true,"slug":"acme","url":"https://.../site/acme"}
GET/api/site/list公開live 200
Lists all published white-label sites with slug, name, updated timestamp and public URL.
レスポンス例
{"ok":true,"sites":[{"slug":"acme","name":"Acme","updated":1780000000000,"url":"https://.../site/acme"}]}
POST/api/site/:slug/unpublish公開
Deletes a published site by slug.
パラメータ位置必須説明
slugpathstringSite slug to remove
レスポンス例
{"ok":true}
GET/site/:slug公開
Serves the published tenant site's raw HTML (not an /api path); 404 HTML page if slug unknown.
パラメータ位置必須説明
slugpathstringPublished site slug
レスポンス例
<!doctype html>...stored site HTML... (or 404 HTML)
POST/api/lead公開
Public lead capture: stores a CRM lead from site widgets/forms.
パラメータ位置必須説明
namebodystringContact name (<=120)
emailbodystringEmail (<=160)
companybodystringCompany (<=160); at least one of name/email/company required
phonebodystringPhone (<=40)
messagebodystringMessage (<=1500)
sourcebodystringSource tag (<=60), default 'web'
tenantbodystringOwning tenant (<=80)
リクエスト
{"name":"..","email":"..","company":"..","message":".."}
レスポンス例
{"ok":true,"id":"L-xxxx"}
GET/api/leads公開live 200
Returns all CRM leads (newest first).
レスポンス例
{"ok":true,"leads":[{"id":"L-..","name":"QA Test","email":"qa@example.com","source":"signup","status":"new","created":1784675609773}]}
POST/api/lead/:id公開
Updates a lead's status/notes/contact fields.
パラメータ位置必須説明
idpathstringLead id
statusbodystringLead status
notesbodystringNotes (<=3000)
name/company/email/phonebodystringContact fields (<=200)
リクエスト
{"status":"contacted","notes":".."}
レスポンス例
{"ok":true,"lead":{...}} | 404 {"ok":false}
POST/api/lead/:id/delete公開
Deletes a lead by id.
パラメータ位置必須説明
idpathstringLead id
レスポンス例
{"ok":true}
POST/api/sign/create公開
Creates a signable e-signature document (quote/contract) and returns its signing URL.
パラメータ位置必須説明
titlebodystringDoc title (<=160), default '御見積書'
clientbodystringClient name (<=120)
emailbodystringSigner email (<=160)
amountbodystringAmount label (<=40)
bodyHtmlbodystringDocument body HTML (<=200000)
リクエスト
{"title":"..","client":"..","amount":"..","bodyHtml":".."}
レスポンス例
{"ok":true,"id":"SG-xxxx","url":"https://.../sign.html?id=SG-xxxx"}
GET/api/sign/:id公開live 404
Fetches a signable document (public signing page reads this).
パラメータ位置必須説明
idpathstringDocument id SG-xxxx
レスポンス例
{"ok":true,"doc":{"id":"SG-..","title":"..","status":"pending",...}} | 404 {"ok":false,"error":"not found"}
POST/api/sign/:id/submit公開
Signs a document: records signer name/signature/timestamp/IP and marks status 'signed'.
パラメータ位置必須説明
idpathstringDocument id
namebodystringSigner name (<=120)
agreedbodybooleanConsent flag; 400 if false/missing
signaturebodystringSignature image data (<=200000)
リクエスト
{"name":"..","agreed":true,"signature":"data:.."}
レスポンス例
{"ok":true,"status":"signed","signedAt":1780000000000}
GET/api/sign/:id/status公開live 404
Returns just the signing status of a document.
パラメータ位置必須説明
idpathstringDocument id
レスポンス例
{"ok":true,"status":"pending","signedName":"","signedAt":0} | 404 {"ok":false}
GET/api/signs公開live 200
Lists all e-signature documents (metadata, newest first).
レスポンス例
{"ok":true,"signs":[{"id":"SG-..","title":"..","client":"..","status":"pending","created":..}]}
POST/api/booking公開
Public consultation booking; also creates a linked CRM lead with status 'meeting'.
パラメータ位置必須説明
namebodystringName (<=120)
emailbodystringEmail (<=160); at least one of name/email required
companybodystringCompany (<=160)
phonebodystringPhone (<=40)
whenbodystringRequested time (<=60)
topicbodystringTopic (<=400)
リクエスト
{"name":"..","email":"..","when":"..","topic":".."}
レスポンス例
{"ok":true,"id":"B-xxxx"}
GET/api/bookings公開live 200
Lists all consultation bookings (newest first).
レスポンス例
{"ok":true,"bookings":[{"id":"B-..","name":"..","email":"..","status":"requested","created":..}]}
POST/api/booking/:id公開
Updates a booking's status.
パラメータ位置必須説明
idpathstringBooking id
statusbodystringNew status (<=30)
リクエスト
{"status":"confirmed"}
レスポンス例
{"ok":true,"booking":{...}} | 404 {"ok":false}
POST/api/referral公開
Creates or updates a referral code for a referrer and returns the shareable ?ref= URL.
パラメータ位置必須説明
referrerbodystringReferrer name (<=120), default '紹介者'
codebodystringDesired code (<=24); auto-generated if omitted
リクエスト
{"referrer":"..","code":".."}
レスポンス例
{"ok":true,"code":"abc12","url":"https://.../?ref=abc12"}
GET/api/referrals公開live 200
Lists all referral codes with click/lead counts.
レスポンス例
{"ok":true,"referrals":[{"code":"abc12","referrer":"..","clicks":0,"leads":0,"created":..}]}
POST/api/referral/:code/track公開
Increments the click counter for a referral code.
パラメータ位置必須説明
codepathstringReferral code (case-insensitive)
レスポンス例
{"ok":true}
POST/api/signup公開
Self-service trial signup: creates a trial (Starter) tenant and a linked CRM lead, returns the prospect app URL.
パラメータ位置必須説明
emailbodystringEmail (<=160); 400 if empty
companybodystringCompany (<=80), used as tenant name
namebodystringContact name (<=80)
planbodystringRequested plan label (stored in lead message)
リクエスト
{"email":"..","company":"..","name":".."}
レスポンス例
{"ok":true,"tenant":{"id":"t-..","name":".."},"url":"https://.../app?prospect=.."}
POST/api/partner公開
Partner/agency program application; creates a partner record + referral code + linked lead.
パラメータ位置必須説明
companybodystringCompany (<=120); 400 if empty
emailbodystringEmail (<=160); 400 if empty
contactbodystringContact name (<=120)
regionbodystringRegion (<=60)
notebodystringNote (<=800)
リクエスト
{"company":"..","email":"..","contact":"..","region":".."}
レスポンス例
{"ok":true,"id":"P-xxxx","code":"acme12","referralUrl":"https://.../?ref=acme12"}
GET/api/partners公開live 200
Lists all partner applications (newest first).
レスポンス例
{"ok":true,"partners":[{"id":"P-..","company":"..","email":"..","tier":"Silver","status":"applied","code":".."}]}
POST/api/partner/:id公開
Updates a partner's status/tier/deals/revenue/note.
パラメータ位置必須説明
idpathstringPartner id
status/tier/notebodystringText fields (<=800)
deals/revenuebodynumberNumeric metrics (coerced with +)
リクエスト
{"status":"active","tier":"Gold","deals":3,"revenue":500000}
レスポンス例
{"ok":true,"partner":{...}} | 404 {"ok":false}
POST/api/review公開
Public review/NPS submission (stored unapproved pending moderation).
パラメータ位置必須説明
commentbodystringReview text (<=800); 400 if empty
ratingbodynumber1-5 (clamped)
namebodystringName (<=80), default '匿名'
companybodystringCompany (<=120)
npsbodynumber0-10 (clamped), default rating*2
リクエスト
{"rating":5,"comment":"..","name":"..","nps":9}
レスポンス例
{"ok":true}
GET/api/reviews公開live 200
Lists approved reviews with computed average rating, count and NPS score.
レスポンス例
{"ok":true,"reviews":[{"id":"RV-965da4","name":"情シス部長","company":"北斗商事","rating":5,"nps":9,...}],"avg":4.7,"count":3,"nps":..}
GET/api/events公開live 200
Returns the static list of 3 upcoming webinars/events.
レスポンス例
{"ok":true,"events":[{"id":"ev-mdm","title":"30分でわかる:Intune × キッティング自動化","date":"2026-08-05 15:00","seats":100}]}
POST/api/event/:id/register公開
Registers for a webinar; creates a linked CRM lead (source 'webinar').
パラメータ位置必須説明
idpathstringEvent id (ev-mdm|ev-lcm|ev-ai)
emailbodystringEmail (<=160); 400 if empty
namebodystringName (<=120)
companybodystringCompany (<=160)
リクエスト
{"email":"..","name":"..","company":".."}
レスポンス例
{"ok":true} | 404 {"ok":false} for unknown event
POST/api/ab公開
Records an A/B landing test event (view or convert) for variant a or b.
パラメータ位置必須説明
variantbodystring'a' or 'b' (default 'a')
eventbodystring'view' or 'convert' (default 'view')
リクエスト
{"variant":"b","event":"convert"}
レスポンス例
{"ok":true}
GET/api/ab公開live 200
Returns current A/B test counters for variants a and b.
レスポンス例
{"ok":true,"stats":{"a":{"view":0,"convert":0},"b":{"view":1,"convert":0}}}
GET/api/export/statetokenlive 401
Full runtime-data dump (all in-memory collections + counts) for automated backups; requires the backup token.
パラメータ位置必須説明
tokenquerystringBackup token; alternatively X-Backup-Token header. Must equal BACKUP_TOKEN
レスポンス例
{"ok":false,"error":"unauthorized"} (no token) | {"ok":true,"exportedAt":..,"tenants":{..},"leads":{..},"counts":{..}}
GET/healthz公開live 200
Health check.
レスポンス例
{"status":"ok"}
該当するエンドポイントがありません。

機械可読仕様: /openapi.json(OpenAPI 3.0)