06 / WEB API
外部連携(WebAPI)
「いまの OEE を出したい」「実績を送りたい」など、やりたいことから探せる外部連携の案内です。先頭に AI Agent 向けチートシートがあり、末尾に Real Time OEE の設定と実装があります。
AI Agent チートシート
人が仕様を読みながらコードを書く代わりに、チートシートを AI Agent に読み込ませ、「やりたいこと」を尋ねてコードを書いてもらうための節です。下の契約(チートシート)はコピーしてエージェントに渡せます。
使い方(ステップ)
- 下のアコーディオンを開き、コピーでチートシート全文を取得する
- 使っている AI Agent の会話・ルール・プロンプトに貼り付けて読み込ませる(キー文字列は含めない)
- やりたいことを自然文で伝える(例: 「今日の現場 ASM のライブ OEE を取る Python を書いて」/「実績をバッチ登録するスクリプトを」)
- エージェントが書いたコードを確認し、必要なら修正を依頼する
- 実行前に認証の渡し方を決める(次項)。キーの値をチャットに貼らない
エージェント向けチートシートを開く/閉じる
# DELTA WebAPI — Agent cheat sheet (safe use)
Base (production): https://delta.956.jp/api/v1
Auth: Authorization: Bearer <api key>
Prefer reading from environment variable DELTA_WEBAPI_KEY (or the host secret store).
Embedding the key in local/private code is allowed if the human chooses; never commit or share that value.
Never ask the user to paste the key into chat. Never print, log, or commit the key value.
Content-Type: application/json
Times: ISO8601 with offset (e.g. 2026-08-24T09:00:00+09:00)
Ids: prefer workplace/work/worker/sku *codes* from DELTA masters; responses may include public_id (UUID).
## Hard rules (do not violate)
- Call ONLY DELTA host endpoints under /api/v1 (not the partner MES/BI host).
- Scope is the organization of the API key. Never attempt cross-tenant access.
- Do not invent paths, fields, or event names. If unsure, stop and ask a human.
- Writes: always send Idempotency-Key and a stable external_id when available.
- defect_quantity must be <= actual_quantity.
- pause creates NonProduction kind=other; resume closes it; humans may reclassify later.
- Do NOT use API for: browser login, kiosk/staff QR sessions, daily-report planned stops as job pause, changing OEE formulas.
- Prefer least privilege: read-only key for dashboards; write key only when registering records/instructions.
- If no key is available (env unset and not otherwise provided privately), stop and ask the human how they want to supply it (do not invent a key).
- Never echo the key in curl -v, debug dumps, screenshots, chat, or commit messages.
## Read (取得系)
GET /workplaces?code=&active=all|true|false&include_streams=true|false
GET /work_masters?workplace_id={code_or_id}&code=&active=all|true|false
GET /workers?retired=false|true|all&code=&active=all|true|false
GET /skus?code=&active=all|true|false
GET /work_record_items?work_date_from=YYYY-MM-DD&work_date_to=YYYY-MM-DD&work_record_status=draft|confirmed|all
GET /work_record_items/{id}
GET /work_instructions?status=open|cancelled|consumed|all&workplace_id={code_or_id}
GET /workplaces/{code_or_id}/oee/live?window=shift_today|day|last_1h
GET /oee?from=YYYY-MM-DD&to=YYYY-MM-DD&group_by=workplace|work_master|worker
GET /non_productions?from=ISO&to=ISO&status=open|closed|all
GET /workplaces/{code_or_id}/non_productions?from=ISO&to=ISO&status=open|closed|all
## Write (登録系)
POST /workplaces | PATCH /workplaces/{code_or_id} (scope write:masters)
POST /work_masters | PATCH /work_masters/{code_or_id} (workplace_code required on create)
POST /workers (pin required) | PATCH /workers/{code_or_id}
POST /skus | PATCH /skus/{code_or_id}
POST /work_record_items/batch
body.items[]: external_id, workplace_code, worker_code, work_master_code, sku_code?,
planned_quantity, actual_quantity, defect_quantity, started_at, ended_at,
standard_cycle_time_sec?, non_productions[]?, instruction_no?
options: on_missing_master=error, wrap_up=true|false
POST /work_instructions
body: instruction_no, sku_code, work_master_code, workplace_code, planned_quantity, due_date?, external_id?
POST /work_instructions/{id}/events
body.event: start|pause|resume|qty_update|stop|wrap_up
body: at?, worker_code?, workplace_code?, actual_quantity?, defect_quantity?, note?, non_productions[]?
Typical flow: start → (qty_update|pause/resume)* → stop → wrap_up
## Real Time OEE
POST /oee/streams/ticks (scope write:oee_streams)
Cumulative snapshot: workplace/line/equipment (any one+), at, run_time_sec (operating),
stop_time_sec?, total_count, defect_count, ideal_cycle_time_sec?
GET /oee/streams/live?workplace=&line=&equipment=&window=30m&points=48 (scope read:oee_streams)
GET /oee/streams/live/stream?... (SSE; same params)
Embed: /widget/rt-oee.js with data-workplace/line/equipment/window/target/token
GET /workplaces/{code_or_id}/oee/live/stream?window=... (scope read:oee; SSE)
## Webhooks (管理)
GET/POST /webhooks | GET/PATCH/DELETE /webhooks/{id} (scope write:webhooks)
POST /webhooks/{id}/test | /rotate_secret | /disable | /enable
Incoming events: HTTPS POST to your URL, header X-Delta-Signature (admin UI or API above).
## When blocked
- Missing master codes → create masters in DELTA admin first (or report error; do not invent).
- Duplicate start on same instruction → conflict; do not retry start blindly.
- Endpoint not listed above → treat as unavailable; do not guess.
Status: read and write endpoints published. OpenAPI: GET /api/v1/openapi.json (no auth).
Webhooks: /api/v1/webhooks (scope write:webhooks) or admin UI /admin/webhooks (HTTPS push, X-Delta-Signature).
SSE live: GET .../oee/live/stream (read:oee), GET /oee/streams/live/stream (read:oee_streams).
キーを見せない・渡さない
チートシートとエージェントへの依頼には使い方だけを入れ、管理画面で発行したキー文字列そのものは入れません。チャット・ログ・コミット・スクリーンショットにも貼らないでください。
実行時の渡し方は、エージェント案でもユーザー判断でも構いません。例:
- 環境変数 … 名前は
DELTA_WEBAPI_KEY(ハイフン不可)。シェルや実行環境のシークレットに値を置き、コードはそれを読んでAuthorization: Bearer …に使う - プログラムへの埋め込み … 試作や閉じた環境向け。リポジトリや共有先にキーが乗らないよう注意する
未設定や権限不足なら、エージェントはキー値を推測せず止まって、人に設定を促すのが安全です。
接続の基本
どの「やりたいこと」でも共通です。先にここを決めてから、個別の呼び出しに進みます。
接続先
呼び先はDELTA 側のホストです(連携先の MES/BI などのホストではありません)。
https://delta.956.jp/api/v1
検証環境など別ホストで DELTA を動かしている場合は、その DELTA のホストに読み替えてください。
OpenAPI
エージェントやクライアント生成向けに、公開済みエンドポイントの機械可読な契約を配信しています(認証不要)。
GET /api/v1/openapi.json
人間向けの説明はこのページ、実装メモは開発用 docs/web_api_dev.md を参照してください。
認証
管理者が発行した API キーを、すべてのリクエストに付けます。キーは組織に紐づき、他組織のデータには届きません。発行・失効は管理画面の APIキー から行います。
Authorization: Bearer dk_live_xxxxx
- 管理画面の APIキー でキーを発行し、権限(
read:oee/write:recordsなど)を付ける - 外部システム側の設定にキーを保存する(ソースコードに直書きしない)
- 漏洩・退職・システム廃止のときはキーを失効する
書込みの再送
実績や指示の登録では、同じ内容を二度送っても二重登録しないよう、Idempotency-Key(推奨)と、外部側の行 ID(external_id)を使います。
Idempotency-Key: mes-batch-20260824-001
時刻・コード
- 時刻は ISO8601(例:
2026-08-24T09:00:00+09:00) - 現場・作業・作業員・SKU は、管理画面で登録したコードで指定できる
- 応答では
public_id(UUID)も返す想定(以降の参照に使える)
いまの現場 OEE を見る 提供中
こんなときに … 行灯・大型モニタ・BI に「この現場のいま」を出したい。
呼び出し
GET /api/v1/workplaces/{現場のIDまたはコード}/oee/live
?window=shift_today
GET /api/v1/workplaces/{現場のIDまたはコード}/oee/live/stream
?window=shift_today
window の例: shift_today(今日のシフト) / day(当日) / last_1h(直近1時間)。/stream は Server-Sent Events(変更時のみ event: live で push)。
手順
- 対象現場のコード(または ID)を決める
- 上記 URL を定期的に取得する(例: 10〜30 秒ごと)
- 返ってきた OEE・可動・性能・品質と、計測中ジョブの一覧を画面に映す
返ってくるもの(イメージ)
- 現場の集計スコア(OEE / A / P / Q)と数量・時間の合計
- いま計測中の作業(作業名・SKU・作業員・ライブ OEE)
- 比較用の目標値(設定している場合)
- 計算できないときは、無理に 0 にせず「計算不可」と分かるフラグ
数字の意味は OEE 入門 と同じです。
期間の OEE を取る 提供中
こんなときに … 「先週の現場別」「今月の作業員別」をレポートや他 DB に取り込みたい。
呼び出し
GET /api/v1/oee
?from=2026-08-01
&to=2026-08-23
&group_by=workplace
group_by: workplace(現場) / work_master(作業) / worker(作業員)
絞り込み(任意): workplace_id / work_master_id / worker_id / org_unit_id / capture_mode
手順
- 期間(from / to)と、まとめ方(group_by)を決める
- 必要なら現場・作業・作業員で絞り込む
- 返ってきた行(キー+スコア+件数・数量)を表やグラフにする
管理画面の OEE/作業員レポートと同じ集計を、外部から読むイメージです。
停止を一括で取る 提供中
こんなときに … 他システム側にダッシュボードがあり、「いま/今日、DELTA で何が止まっているか」を一覧で取り込みたい。組織全体でも、特定現場だけでも取れます。
呼び出し
# 組織全体(キーの組織スコープ)
GET /api/v1/non_productions
?from=2026-08-24T00:00:00+09:00
&to=2026-08-24T23:59:59+09:00
&status=open|closed|all
# 所定の現場だけ
GET /api/v1/workplaces/{現場のコードまたはID}/non_productions
?from=…
&to=…
&status=open
status の例: open(継続中の停止) / closed(終了済み) / all(両方)
手順
- ダッシュボードの更新周期に合わせて、上記を定期取得する
- 全体監視なら組織向け、ライン別モニタなら現場向け URL を使う
- 返ってきた各停止の理由・開始/終了・分数・紐づく現場/作業/作業員を表やアラートに載せる
返ってくるもの(イメージ)
- 非稼働の一覧(理由 kind、開始・終了、duration、メモ)
- 紐づき(現場・作業・作業員・作業記録)
- ページング(件数が多い日向け)
主に作業に紐づく非稼働(可動 A に効くロス)です。日報の予定外停止との違いは 作業員端末の説明 を参照。
マスタを同期する 提供中
こんなときに … 連携システム側で DELTA のコード表を揃えたい。実績や指示を送る前に、現場・作業・作業員・SKU の一覧を取得します。
呼び出し
GET /api/v1/workplaces
GET /api/v1/work_masters?workplace_id={現場コードまたはID}
GET /api/v1/workers
GET /api/v1/skus
権限は read:masters(取得)と write:masters(登録・更新)。ページングは page / per_page(最大 200)。code で完全一致検索、active=true|false|all で有効/無効を絞れます。
書き込み
POST /api/v1/workplaces
PATCH /api/v1/workplaces/{idまたはcode}
POST /api/v1/work_masters (workplace_id または workplace_code 必須)
PATCH /api/v1/work_masters/{idまたはcode}
POST /api/v1/workers (pin 必須)
PATCH /api/v1/workers/{idまたはcode}
POST /api/v1/skus
PATCH /api/v1/skus/{idまたはcode}
変更系は Idempotency-Key ヘッダーを推奨します。ストリーム専用現場は更新できません。
- 現場 … 既定は人間向け現場のみ。
include_streams=trueでストリーム専用現場も含む - 作業 …
workplace_idで現場を絞り込み(code 可) - 作業員 … 既定は有効な人間作業員。
retired=allで退職者も含む
返ってくるもの(イメージ)
- 各マスタの
id/code/name(書き込み API は code で指定) - 作業には紐づく現場、作業員には既定現場と退職状態
- ページング情報(
pagination.totalなど)
実績を取る 提供中
こんなときに … MES や会計システムが、DELTA に登録された作業実績を定期的に取り込みたい。
呼び出し
GET /api/v1/work_record_items
GET /api/v1/work_record_items/{id}
権限は read:records。日付を指定しない場合は当日の work_date のみ返します。
work_date_from/work_date_to… 日報の日付で絞り込みstarted_from/started_to… 実績の開始時刻で絞り込み(ISO8601)external_id… 外部システムの行 ID で 1 件検索work_record_status…draft/confirmed/allworkplace_id/worker_id/work_master_id… code または数値 ID
応答には OEE スコア(DELTA ローカル正)と、詳細取得時は non_productions[] が含まれます。
未消化の指示を取る 提供中
こんなときに … スケジューラや MES が、まだ着手していない作業指示の残件を確認したい。
呼び出し
GET /api/v1/work_instructions?status=open
GET /api/v1/work_instructions?status=open&workplace_id={現場コードまたはID}
権限は read:instructions。既定は status=open(未着手)。due_date_from / due_date_to で納期を絞れます。
実績をまとめて登録する 提供中
こんなときに … MES や別システムで確定した「いつ・誰が・何を・何個」を、DELTA の作業実績に載せたい。
呼び出し
POST /api/v1/work_record_items/batch
Authorization: Bearer dk_live_xxxxx
Idempotency-Key: mes-20260824-001
Content-Type: application/json
{
"items": [
{
"external_id": "MES-ROW-1001",
"workplace_code": "ASM",
"worker_code": "S-01",
"work_master_code": "W-01",
"sku_code": "SKU-001",
"planned_quantity": 20,
"actual_quantity": 18,
"defect_quantity": 1,
"started_at": "2026-08-24T09:00:00+09:00",
"ended_at": "2026-08-24T09:45:00+09:00",
"standard_cycle_time_sec": 120,
"non_productions": [
{ "kind": "changeover", "duration_sec": 600, "note": "段取" }
]
}
],
"options": { "on_missing_master": "error", "wrap_up": true }
}
手順
- DELTA に現場・作業・作業員・SKU・標準 CT があることを確認する
- 1 行ごとに
external_idを付けて送る(再送対策) - 応答の行ごとの成功/失敗を見て、失敗行だけ直して再送する
- 管理画面の作業実績で、取り込めたか確認する
よくある失敗
- コードがマスタに無い → 先に管理画面で登録
- 不良数が生産数より多い → 画面と同じく拒否
- 同じ
external_idの再送 → 新規作成せず、既存を返す
指示を登録して実行する 提供中
こんなときに … 生産スケジューラで作った指示を DELTA に渡し、開始〜終了まで同じ指示に紐づけて追いたい。現場では QR でも読ませたい。
1. 指示を登録する
POST /api/v1/work_instructions
{
"instruction_no": "WI-2026-0042",
"sku_code": "SKU-001",
"work_master_code": "W-01",
"workplace_code": "ASM",
"planned_quantity": 100,
"due_date": "2026-08-25",
"external_id": "MES-WO-7788"
}
応答には指示の ID と、現場端末向け DELTA WI JSON(作業指示 QR と同じ形)が付きます。仕様の背景は 管理者向け・作業指示書 QR を参照。
2. 実行イベントを送る
POST /api/v1/work_instructions/{id}/events
Idempotency-Key: wi-42-start-1
{
"event": "start",
"at": "2026-08-24T10:00:00+09:00",
"worker_code": "S-01",
"workplace_code": "ASM"
}
| event | いつ送るか | 次にできること |
|---|---|---|
start | 計測を始めるとき | 数量更新・一時停止・終了 |
pause / resume | 途中で止まった/再開したとき | 一時停止の節 |
qty_update | 生産数・不良を途中で直すとき | 続けて計測または終了 |
stop | 作業を切り上げるとき | 確定(wrap_up) |
wrap_up | 数量・非稼働を確定して完了させるとき | 完了(再 start は原則不可) |
手順(典型)
- 指示を登録する → 返ってきた ID を保存する
start→ 必要ならqty_update/pause・resumestop→wrap_up(最終の生産数・不良・非稼働)- 現場で QR からも始める場合は、二重 start にならないよう運用を決める(衝突時はエラー)
一時停止を記録する 提供中
こんなときに … 設備やラインが止まったことを可動(A)に反映したい。理由の細かい分類は後で直したい。
呼び出し
# 止まる
POST /api/v1/work_instructions/{id}/events
{ "event": "pause", "at": "2026-08-24T10:20:00+09:00", "note": "api:pause" }
# 再開する
POST /api/v1/work_instructions/{id}/events
{ "event": "resume", "at": "2026-08-24T10:35:00+09:00" }
DELTA 側の動き
pause… その作業に紐づく非稼働を自動作成。理由は当面「その他」resume… その非稼働の終了時刻・分数を確定- あとから管理画面・現場端末・API で、段取・材料待ち・故障など正しい理由に置き換え
日報の予定外停止(会議・教育など、特定作業に紐づけない枠)とは別です。違いは 作業員端末の説明 を参照。
イベントを Webhook で受け取る 提供中
外部システムへ DELTA のイベントをプッシュします。受信 URL の登録は管理画面(/admin/webhooks)または API(write:webhooks)で行います。
設定場所
管理画面の 連携 → Webhook(/admin/webhooks)または GET/POST/PATCH/DELETE /api/v1/webhooks。無料枠は組織あたり 1 件。追加枠はプラン画面の Webhook 契約から購入できます。テスト送信・配信ログ・Secret の再発行ができます。
API で管理する(write:webhooks)
GET /api/v1/webhooks
POST /api/v1/webhooks
GET /api/v1/webhooks/{id}
PATCH /api/v1/webhooks/{id}
DELETE /api/v1/webhooks/{id}
POST /api/v1/webhooks/{id}/test
POST /api/v1/webhooks/{id}/rotate_secret
POST /api/v1/webhooks/{id}/disable
POST /api/v1/webhooks/{id}/enable
作成時と Secret 再発行時のみ、レスポンスに secret が含まれます。管理画面と併用できます。
イベント種別
work_record_item.stopped… 作業停止後work_record_item.wrapped_up… 数量確定(wrap-up)後work_record.confirmed… 日報確定後oee.below_target… 選択した OEE 指標が目標を下回った瞬間(現場ライブ/ストリームライブ)
署名
各 POST に X-Delta-Signature: t=<unix>,v1=<hmac> が付きます(HMAC-SHA256、エンドポイントごとの Secret)。受信側は event.id で重複排除してください。順序は保証されません(at-least-once)。
共通フォーマット
{
"id": "evt_…",
"type": "work_record_item.wrapped_up",
"created_at": "2026-09-02T10:05:00+09:00",
"organization_id": 1,
"data": { }
}
data.work_record_item の形は read API の実績レスポンスと同型です。OpenAPI は GET /api/v1/openapi.json を参照(Webhook 管理 API 含む)。
ストリームとは 提供中
こんなときに使う
外部 MES/PLC/カウンタから「いまの累積稼働・数量」を DELTA に送り、大型モニタや MES 画面にリアルタイム OEE 行灯(Widget)を埋め込みたいとき。
通常の現場ライブ OEE(作業記録ベース)とは別経路です。ストリームキー(workplace / line / equipment)単位で累積ティックを受け取り、最新スナップショットから OEE・可動(A)・性能(P)・品質(Q) を計算して Widget に表示します。
レポートの現場としても扱える
ストリームを登録すると、レポート用の専用現場が自動で紐づきます。受信ティックはその日の作業実績へ投影され、レポート/現場 や 作業実績 で期間集計・比較できます。
- 専用現場の名称はストリームの表示名と同期します(コードは
oee-stream-{id}) - 現場端末用 QR は発行しません(ストリーム専用のため)
- ストリームを削除しても、専用現場と投影済みの作業実績は残ります
- 組織のストリーム枠は既定 1 件。追加は運用コースの Stream×3(3万円/月・外税)/×5(4万円)/×10(7万円)。解約で枠は 1 に戻り、最古以外のストリームは削除
データの流れ
POST
外部システムが累積スナップショットを POST /api/v1/oee/streams/ticks する
蓄積
DELTA がストリームにティックを蓄積し、日次の作業実績(レポート用現場)へも投影する
表示
Widget(またはライブ GET)が最新ティックの累積値から OEE・可動(A)・性能(P)・品質(Q) を算出し、グラフは選択窓内の推移を描画する
累積ティックの意味(必ず守る)
各 POST は「その時点までの累計」です(増分だけを送る方式ではありません)。シフト開始でカウンタをリセットしたら、次のティックから新しい累計として送れば DELTA 側でリセットを検知します。スコアボードの可動率 A は最新ティックの累積で 実稼働 ÷ (実稼働 + 停止) です。グラフの時間窓は描画レンジのみです。
run_time_sec
実稼働(製品を作っている時間)の累積秒
stop_time_sec
停止の累積秒
total_count / defect_count
生産数・不良数の累積
ideal_cycle_time_sec
1 個あたりの理想 CT(秒)。性能(P) の計算に必要
必要な API スコープ
| 用途 | スコープ | エンドポイント |
|---|---|---|
| 外部からティック送信 | write:oee_streams | POST /api/v1/oee/streams/ticks |
| Widget/BI がライブ取得 | read:oee_streams | GET /api/v1/oee/streams/live |
| ライブ SSE(ストリーム) | read:oee_streams | GET /api/v1/oee/streams/live/stream |
| ライブ SSE(現場) | read:oee | GET /api/v1/workplaces/{id}/oee/live/stream |
送信用と埋め込み用でキーを分けることを推奨します。埋め込み HTML の data-token には read のみのキーを入れてください。
DELTA 側の設定
管理画面でストリームと API キーを整え、埋め込みコードを発行するまでの手順です。
API キーを発行する
- 管理画面の APIキー を開く
- 書き込み用キーを発行し、権限に
write:oee_streamsを付ける(外部システムのシークレットに保存) - 読み取り用キーを発行し、権限に
read:oee_streamsを付ける(Widget のdata-token用) - 平文キーは管理画面の一覧からコピーできます。チャットや git に貼らない

ストリームを登録する
- サイドメニュー 運用設定 → 連携 → ストリームを開く
- 画面上部のストリーム枠(使用数 / 上限)を確認する。既定上限は 1 件。足りない場合は 運用コース で Stream×3 / ×5 / ×10 を契約する
- 表示名と、キー(
workplace/line/equipment)を入力する。いずれか1つ以上必須 - 「追加する」でストリームを作成する(同時にレポート用の専用現場が紐づく)
キー文字列は、外部システムが POST する JSON の同名フィールドと完全一致させてください。未登録キーで POST すると自動作成もされますが、枠上限を超える新規キーは拒否されます。先に画面で揃えるのが安全です。レポート側での見方は上の「レポートの現場としても扱える」を参照。

キーと受信を確認する
- 一覧から「詳細・ティック」を開く
- 上部のキーボードで
stream_key・workplace / line / equipment・最終ティックを確認する - 「受信ティック」タブで POST された累積スナップショットが新しい順に並ぶことを確認する
- 試験データが不要なら「データクリア」で範囲を選んで削除できる(復元不可)

埋め込みコードを作る
- 「埋め込み」タブを開く
- テーマ(dark / light / compact 組み合わせ)、窓(30分〜3時間)、目標 OEE(%)を選ぶ
- プレビューが約5秒ごとに更新されることを確認する(管理画面セッション経由)
- 「埋め込みコードをコピー」で HTML を取得し、
data-tokenを読み取り用キーに置き換える - 自社ページや MES の HTML に貼り付ける

WebAPI 連携タブで契約を確認する
「WebAPI 連携」タブには、このストリーム向けの POST / GET 例が載っています。外部実装のたたき台として使えます。

埋め込み HTML の形
<!-- DELTA R/T Widget -->
<div class="delta-rt-oee-wrap theme-dark">
<div id="rt-oee-1"
class="delta-rt-oee theme-dark"
data-workplace="FIN"
data-line="LINE-A"
data-equipment="EQ-01"
data-window="30m"
data-target="0.85"
data-token="YOUR_EMBED_TOKEN"></div>
</div>
<script src="https://delta.956.jp/widget/rt-oee.js" async></script>
data-window
30m / 1h / 90m / 2h / 150m / 3h(ほか 10m も可)
data-target
目標 OEE の比率(85% → 0.85)。管理画面の入力は % 表示
テーマクラス
theme-dark / theme-light。必要なら theme-compact を併用
外部システムでの実装
外部側は、設備カウンタや MES から得た累積値を JSON にして、定期的に(例: 5〜30 秒ごと)POST します。
エンドポイントとヘッダ
POST https://delta.956.jp/api/v1/oee/streams/ticks
Authorization: Bearer <write:oee_streams のキー>
Content-Type: application/json
Idempotency-Key: mes-tick-FIN-LINE-A-20260827T163000 (推奨)
フィールド定義
| フィールド | 必須 | 内容 |
|---|---|---|
workplace / line / equipment | いずれか1つ以上 | ストリームキー。DELTA 管理画面と同じ文字列 |
at(または observed_at) | 必須 | 観測時刻(ISO8601、例 2026-08-27T16:30:00+09:00) |
run_time_sec | 必須 | 実稼働の累積秒(≥ 0) |
stop_time_sec | 任意(省略時 0) | 停止の累積秒(≥ 0) |
total_count | 必須 | 生産数の累積(整数 ≥ 0) |
defect_count | 必須 | 不良数の累積(≤ total_count) |
ideal_cycle_time_sec | 推奨 | 理想 CT(秒)。無いと性能(P)・OEE が計算できない |
name | 任意 | ストリーム自動作成時の表示名 |
送信例(JSON)
{
"workplace": "FIN",
"line": "LINE-A",
"equipment": "EQ-01",
"at": "2026-08-27T16:30:00+09:00",
"run_time_sec": 3600,
"stop_time_sec": 600,
"total_count": 420,
"defect_count": 3,
"ideal_cycle_time_sec": 85.5
}
成功時は 201 Created。同じ Idempotency-Key の再送は二重登録しません。
実装サンプル(主要言語)
いずれも環境変数 DELTA_WEBAPI_KEY(write:oee_streams)を読む想定です。キー値をソースに書かないでください。
curl
curl -sS -X POST "https://delta.956.jp/api/v1/oee/streams/ticks" \
-H "Authorization: Bearer ${DELTA_WEBAPI_KEY}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: mes-tick-$(date +%Y%m%d%H%M%S)" \
-d '{
"workplace": "FIN",
"line": "LINE-A",
"equipment": "EQ-01",
"at": "2026-08-27T16:30:00+09:00",
"run_time_sec": 3600,
"stop_time_sec": 600,
"total_count": 420,
"defect_count": 3,
"ideal_cycle_time_sec": 85.5
}'
Ruby
require "json"
require "net/http"
require "uri"
require "time"
uri = URI("https://delta.956.jp/api/v1/oee/streams/ticks")
body = {
workplace: "FIN",
line: "LINE-A",
equipment: "EQ-01",
at: Time.now.iso8601,
run_time_sec: 3600,
stop_time_sec: 600,
total_count: 420,
defect_count: 3,
ideal_cycle_time_sec: 85.5
}
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("DELTA_WEBAPI_KEY")}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "mes-tick-#{Time.now.strftime("%Y%m%d%H%M%S")}"
req.body = JSON.generate(body)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
raise "tick failed: #{res.code} #{res.body}" unless res.is_a?(Net::HTTPSuccess)
puts res.body
Python
import json
import os
from datetime import datetime, timezone, timedelta
from urllib import request
JST = timezone(timedelta(hours=9))
payload = {
"workplace": "FIN",
"line": "LINE-A",
"equipment": "EQ-01",
"at": datetime.now(JST).isoformat(timespec="seconds"),
"run_time_sec": 3600,
"stop_time_sec": 600,
"total_count": 420,
"defect_count": 3,
"ideal_cycle_time_sec": 85.5,
}
req = request.Request(
"https://delta.956.jp/api/v1/oee/streams/ticks",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {os.environ['DELTA_WEBAPI_KEY']}",
"Content-Type": "application/json",
"Idempotency-Key": datetime.now(JST).strftime("mes-tick-%Y%m%d%H%M%S"),
},
method="POST",
)
with request.urlopen(req) as res:
print(res.read().decode("utf-8"))
JavaScript(Node.js)
const key = process.env.DELTA_WEBAPI_KEY;
if (!key) throw new Error("DELTA_WEBAPI_KEY is not set");
const at = new Date().toISOString();
const body = {
workplace: "FIN",
line: "LINE-A",
equipment: "EQ-01",
at,
run_time_sec: 3600,
stop_time_sec: 600,
total_count: 420,
defect_count: 3,
ideal_cycle_time_sec: 85.5,
};
const res = await fetch("https://delta.956.jp/api/v1/oee/streams/ticks", {
method: "POST",
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
"Idempotency-Key": `mes-tick-${Date.now()}`,
},
body: JSON.stringify(body),
});
if (!res.ok) {
throw new Error(`tick failed: ${res.status} ${await res.text()}`);
}
console.log(await res.json());
C#
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var key = Environment.GetEnvironmentVariable("DELTA_WEBAPI_KEY")
?? throw new InvalidOperationException("DELTA_WEBAPI_KEY is not set");
var payload = new {
workplace = "FIN",
line = "LINE-A",
equipment = "EQ-01",
at = DateTimeOffset.Now.ToString("o"),
run_time_sec = 3600,
stop_time_sec = 600,
total_count = 420,
defect_count = 3,
ideal_cycle_time_sec = 85.5
};
using var client = new HttpClient();
using var req = new HttpRequestMessage(
HttpMethod.Post,
"https://delta.956.jp/api/v1/oee/streams/ticks");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);
req.Headers.TryAddWithoutValidation("Idempotency-Key", $"mes-tick-{DateTimeOffset.Now:yyyyMMddHHmmss}");
req.Content = new StringContent(
JsonSerializer.Serialize(payload),
Encoding.UTF8,
"application/json");
using var res = await client.SendAsync(req);
res.EnsureSuccessStatusCode();
Console.WriteLine(await res.Content.ReadAsStringAsync());
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
String key = System.getenv("DELTA_WEBAPI_KEY");
if (key == null || key.isBlank()) throw new IllegalStateException("DELTA_WEBAPI_KEY is not set");
String at = OffsetDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
String json = """
{
"workplace": "FIN",
"line": "LINE-A",
"equipment": "EQ-01",
"at": "%s",
"run_time_sec": 3600,
"stop_time_sec": 600,
"total_count": 420,
"defect_count": 3,
"ideal_cycle_time_sec": 85.5
}
""".formatted(at);
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://delta.956.jp/api/v1/oee/streams/ticks"))
.header("Authorization", "Bearer " + key)
.header("Content-Type", "application/json")
.header("Idempotency-Key", "mes-tick-" + System.currentTimeMillis())
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
if (res.statusCode() / 100 != 2) {
throw new IllegalStateException("tick failed: " + res.statusCode() + " " + res.body());
}
System.out.println(res.body());
ライブ取得(参考)
Widget 内部も同じエンドポイントを呼びます。BI から直接取る場合:
GET https://delta.956.jp/api/v1/oee/streams/live
?workplace=FIN&line=LINE-A&equipment=EQ-01
&window=30m&points=48
Authorization: Bearer <read:oee_streams のキー>
よくある失敗
スコープ不足 → 403
write:oee_streams を付けたキーか確認
キー不一致 → 空表示
POST の workplace/line/equipment と埋め込みの data-* を揃える
defect_count > total_count → 422
不良数は生産数以下にする
理想 CT 未送信
ティックは溜まるが性能(P)・OEE が出ない
増分だけを送っている
累積スナップショットに直す