メニュー経路: ダッシュボード > タスク

タスク

概要

タスクは、ChatGPT や Claude などの AI にあなたのサーバー(ワーカー)で作業を実行させる機能です。「ERP に A-1042 を 30 個発注して」と伝えると、AI がワーカーに作業を送り、結果を受け取って会話に表示します。

  • 3Min API は作業を届けて状態を記録するだけで、作業そのものはワーカーが実行します
  • ワーカーは、あなた自身が運用する HTTP サーバーです

いつ使うか

  • 社内システムに作業させたいとき — ERP への発注登録、在庫確認、社内 DB の検索
  • 時間のかかる作業 — レポート生成、大量変換(最大 24 時間)
  • 自分の PC でしか動かないスクリプト — トンネルで公開 URL を付ければ使えます(下記参照

データを保存・収集することが目的なら、エンドポイントが適しています。

ワーカーのコードを書くのが難しければ、普段使っている AI に「3minapi のタスクワーカーを作って」と頼んでみてください。AI は help ツールからこのページと同じ約束事を読み取り、コードを書きます。

このページへのアクセス方法

  • ワーカーの登録: ダッシュボード → タスクワーカー タブ → ワーカーを登録
  • 実行の確認: ダッシュボード → タスク実行履歴 タブ

動作の仕組み

① Web でワーカーを登録            (最初に一度だけ)
② AI → task_create                タスク作成、状態 working
③ 3Min API → ワーカーへ POST      署名付きリクエスト(callback_url を含む)
④ ワーカー → すぐに 2xx を返す    「受け取った」という意味だけで、結果ではない
⑤ ワーカー → callback_url         進捗メッセージ(任意) → completed または failed
⑥ AI → task_get                   結果を確認
どこで すること
Web ダッシュボード ワーカーの登録・編集・削除、シークレットの確認・更新、実行履歴の確認
AI との会話 ワーカー一覧の確認、タスクの送信、状態・結果の確認、キャンセル
ワーカーサーバー リクエストの受信、作業の処理、結果の報告

AI はワーカーの URL とシークレットを見ることができません。どちらも Web でのみ扱います。

ワーカーの登録 (Web)

項目 説明 上限
名前 必須。AI が呼ぶ名前。大文字・小文字を区別せず一意で、登録後は変更不可 50 文字
説明 必須。AI はこの説明を見てワーカーを選びます 500 文字
ワーカー URL 必須。タスクを POST で受け取るアドレス 2,048 バイト
認証ヘッダー / 認証値 任意。ワーカー独自の認証用。値だけ入れるとヘッダーは Authorization 128 / 8,192 バイト
  • 説明は具体的に書いてください。 AI は URL ではなく名前と説明だけを見ます。erp-1 ではなく「社内 ERP に発注を登録し、発注番号を返します」のように、何を受け取り何を返すかを書くと AI が選べます

2つのシークレットは方向が逆

登録すると、シークレットが 2 つ自動で発行されます。ワーカーの詳細画面(ダッシュボード → タスクワーカー タブ → ワーカーを選択)の シークレットを表示シークレットをコピー で確認してください。

シークレット 形式 方向 用途
署名シークレット whsec_... 3Min API → ワーカー 届いたリクエストが本当に 3Min API から来たかを検証
コールバックキー tm_task_... ワーカー → 3Min API 報告するときに Authorization: Bearer で送信
  • 2 つは別の値で、入れ替えて使えません。 エンドポイントの API キー(tm_live_tm_test_)もコールバックキーとしては使えません
変更 動作 ワーカーがすること
署名シークレットを再発行 48 時間は新しいタスクに新旧両方の署名が付く。再発行のタスクの再試行(最大約 5 時間)には以前の署名だけが付く 以前のシークレットを 6 時間以上残してから、48 時間以内に切り替え
コールバックキーを再生成 以前のキーは即座に無効(実行中のタスクも含む) すぐに切り替え

48 時間以内にもう一度再発行すると、最初のシークレットは即座に無効になります。ダッシュボードには現在のシークレットだけが表示されるため、以前のシークレットを残すには再発行する前にコピーしておいてください

ワーカーの実装

ワーカーが守る5つのルール

  1. 15 秒以内に 2xx を返してください。 作業は応答した後に処理します
  2. 作業が失敗しても、リクエストは 2xx で受け取ってください。 失敗は報告で伝えます(5xx は再試行、それ以外の 4xx は即時失敗 — 応答コード
  3. task_id で重複を除いてください。 同じタスクが 2 回届くことがあります(at-least-once)
  4. 署名検証は任意ですが推奨です。 検証しないと、ワーカー URL を知る誰でも偽のタスクを送れます(署名検証
  5. 結果は callback_url に報告してください。 completed または failed1 回送ります。報告がなければ 24 時間後に failed になります(ステータス報告 API

配信リクエスト

3Min API がワーカー URL に送るリクエストです。

POST https://worker.example.com/tasks
Content-Type: application/json
webhook-id: 0199a1b2-...
webhook-timestamp: 1757650867
webhook-signature: v1,K3XkZ1n0...
X-3minapi-Task-Id: 0199a1b2-...
X-3minapi-Delivery-Attempt: 1
Authorization: Bearer xxx
ヘッダー 内容
webhook-id タスク ID(task_id と同じ値)
webhook-timestamp 送信時刻(Unix 秒)。試行ごとに新しくなる
webhook-signature 署名。再発行中はスペース区切りで 2 つ(署名検証
X-3minapi-Task-Id タスク ID(webhook-id と同じ値)
X-3minapi-Delivery-Attempt 何回目の配信試行か(1 から)
登録した認証ヘッダー 登録時に認証ヘッダー・値を入力した場合のみ

本文:

{
	"type": "task.created",
	"timestamp": "2026-09-12T04:21:07.123Z",
	"data": {
		"task_id": "0199a1b2-...",
		"input": { "sku": "A-1042", "qty": 30 },
		"callback_url": "https://api.3minapi.com/api/v1/tasks/0199a1b2-.../result"
	}
}
フィールド 内容
task_id タスク ID。重複除去に使います
input AI が送った JSON オブジェクト(値は同じでもキーの順序は変わることがあります)
callback_url このタスクの報告先 URL。 状態・結果はここに送ります

ワーカーの応答コード

応答の本文は読まず、ステータスコードだけを見ます。

応答 結果
2xx 受付完了。報告が届くまで working
5xx(501・505 を除く)、429、15 秒タイムアウト、接続エラー 30 秒・2 分・10 分・1 時間・4 時間後に再試行、計 6 回(約 5 時間)。429 の Retry-After は長い場合のみ反映
その他の 4xx(401・404・409 など)、501、505 再試行せず即座に failed
  • 署名検証に失敗したら 401 を返してください。シークレットを間違えて入力していれば、最初のタスクからすぐに failed になり、設定の問題にすぐ気づけます

署名検証 (任意)

webhook-signature ヘッダーが署名です。3Min API がワーカーの署名シークレットで計算して付け、ワーカーは同じ計算で一致するかを確認します。

署名対象 = "{webhook-id}.{webhook-timestamp}.{リクエスト本文の生データ}"
キー     = 署名シークレットから whsec_ を除き、base64 デコードしたバイト列
署名     = "v1," + base64( HMAC-SHA256(キー, 署名対象) )
  • 公式の Standard Webhooks ライブラリを使えば数行で済みます(サンプルコード)。言語別パッケージと自前実装の方法は Webhook 署名の検証(同じ規格)を参照してください
  • リクエスト本文の生のバイト列で検証してください。JSON をパースしてから文字列に戻すと必ず失敗します
  • webhook-timestamp が 5 分以上ずれていると、ライブラリが拒否します(リプレイ攻撃の防止)
  • 署名が 2 つ届いた場合は、どちらか一方が一致すれば合格です(再発行のルール
  • 検証しない場合は、少なくとも callback_urlhttps://api.3minapi.com/ で始まるかを確認してください — コールバックキーをそのアドレスに送るためです

ステータス報告 API

配信リクエストで届いた callback_url状態を送ります。進捗メッセージは何度でも、完了・失敗は 1 回だけです。

POST https://api.3minapi.com/api/v1/tasks/{task_id}/result
Authorization: Bearer tm_task_...
Content-Type: application/json
  • URL: callback_url はこの形式にタスク ID が埋め込まれた状態で届きます。自分で組み立てず、そのまま使ってください
  • コールバックキー: ワーカー詳細画面の コールバックキーシークレットをコピー。ワーカーサーバーの環境変数などに保存してください

進行中 — タスクは working のままで、AI は task_get でメッセージを確認します

{ "status": "working", "status_message": "1/2 在庫を確認中" }

完了

{
	"status": "completed",
	"result": { "order_id": "PO-20260912-001" },
	"status_message": "発注 PO-20260912-001 を登録しました"
}

失敗

{
	"status": "failed",
	"error": { "code": 1001, "message": "在庫不足", "data": { "available": 12 } }
}
フィールド ルール
status workingcompletedfailed のいずれか
status_message working では必須、それ以外は任意。256 文字を超えた分は切り捨てfailed で省略すると error.message が入る
result completed では必須。null 以外の任意の JSON
error failed では必須。code(整数)+ message(文字列)、data は任意
  • 本文全体を 100 KB 以下にしてください。resulterror は切り捨てられないため、超えると報告全体が 413 で拒否されます
  • 受け付けられた報告 1 回 = API 呼び出し 1 回。進捗メッセージは意味のある段階でだけ送ってください

ステータス報告 API の応答コード

コード 意味 ワーカーの対応
202 受付済み。通常は数秒以内に反映
400 本文の形式エラー、不正なタスク ID、文字列内の NUL 文字 コードを修正
401 コールバックキーがない・誤り(エンドポイントの API キーを含む) キーを確認
404 このワーカーのタスクではない callback_url を確認
409 すでに終了したタスク(完了・失敗・キャンセル) 報告をやめる
413 本文が 100 KB を超過。何も記録されない タスクがまだ working なら縮めて再送
415 Content-Type が JSON ではない ヘッダーを修正
503 一時的な障害 少し待って再送

サンプルコード (Node.js)

Node.js 18 以上と、package.json"type": "module" が必要です。

// npm i express standardwebhooks
import express from 'express';
import { Webhook } from 'standardwebhooks';

// 署名シークレット(whsec_...)とコールバックキー(tm_task_...)は別の値です
const wh = new Webhook(process.env.TASK_SIGNING_SECRET.replace('whsec_', ''));
const CALLBACK_KEY = process.env.TASK_CALLBACK_KEY;
// 受け付けた task_id — 本番では DB や Redis に保存してください
const seen = new Set();

const app = express();

// 署名は生のバイト列で計算されます。JSON をパースすると検証に失敗します。
app.post('/tasks', express.raw({ type: 'application/json' }), (req, res) => {
	let envelope;
	try {
		envelope = wh.verify(req.body, {
			'webhook-id': req.header('webhook-id'),
			'webhook-timestamp': req.header('webhook-timestamp'),
			'webhook-signature': req.header('webhook-signature')
		});
	} catch {
		return res.sendStatus(401);
	}

	const { task_id, input, callback_url } = envelope.data;

	// ルール 3 — 受け付け済みのタスクは再処理しない
	if (seen.has(task_id)) return res.sendStatus(202);
	seen.add(task_id);

	// ルール 1 — 先に応答し、作業はその後で
	res.sendStatus(202);
	run(input, callback_url);
});

async function run(input, callbackUrl) {
	try {
		// 進捗メッセージ — タスクは working のまま、AI は task_get で確認します
		await report(callbackUrl, { status: 'working', status_message: '1/2 在庫を確認中' });
		await checkStock(input); // ← 実際の作業

		await report(callbackUrl, { status: 'working', status_message: '2/2 発注を登録中' });
		const orderId = await createOrder(input);

		// 完了 — 結果と要約メッセージ
		await report(callbackUrl, {
			status: 'completed',
			result: { order_id: orderId },
			status_message: `発注 ${orderId} を登録しました`
		});
	} catch (err) {
		// ルール 2 — 作業や報告が失敗したら failed を報告
		await report(callbackUrl, {
			status: 'failed',
			error: { code: 1001, message: String(err?.message ?? err) },
			status_message: '発注の登録に失敗しました'
		}).catch(console.error);
	}
}

// callbackUrl — 配信リクエストの callback_url をそのまま使う
async function report(callbackUrl, body) {
	for (let attempt = 1; attempt <= 3; attempt++) {
		const res = await fetch(callbackUrl, {
			method: 'POST',
			headers: {
				Authorization: `Bearer ${CALLBACK_KEY}`,
				'Content-Type': 'application/json'
			},
			body: JSON.stringify(body)
		}).catch(() => null);

		// 202 受付、409 すでに終了したタスク — これ以上送る必要なし
		if (res?.status === 202 || res?.status === 409) return;
		// 400・401・404・413 は再送しても同じ結果
		if (res && res.status !== 503) throw new Error(`report rejected: HTTP ${res.status}`);
		// 503・ネットワークエラーだけ少し待って再試行
		if (attempt < 3) await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt));
	}
	throw new Error('report failed: service unavailable');
}

app.listen(8080);

自分のPCでワーカーを動かす

ワーカーにはインターネットから届く公開 URL が必要です。ルーターの内側にある PC なら、トンネルでローカルのポートに公開 HTTPS アドレスを付けてください。

cloudflared tunnel --url http://localhost:8080
ngrok http 8080
  • インストールと使い方: Cloudflare Quick Tunnelsngrok はじめに
  • 表示されたアドレスにパスを付けて(例: https://xxxx.trycloudflare.com/tasksワーカー URL として登録します
  • アカウントなしの一時アドレスは起動するたびに変わります。 そのたびにワーカー URL を更新するか、各サービスの固定アドレス機能を使ってください
  • PC の電源が切れている、またはトンネルが切れている場合、たいていは再試行(約 5 時間)の後に failed になります。停止中のアドレスに 404 を返すサービスでは、すぐに failed になります

タスクの送信 (AI)

ワーカーを登録すれば、AI との会話ですぐに使えます。ツール名を知る必要はありません。

  • 「ERP に A-1042 を 30 個発注して」
  • 「さっき送った発注はどうなった?」
  • 「今送ったタスクをキャンセルして」
ツール すること
worker_list 登録済みワーカーの名前と説明(URL・シークレットは見えない)
task_create ワーカーの名前input(JSON オブジェクト、100 KB 以下)でタスクを作成
task_get タスク 1 件の状態、メッセージ、結果またはエラー
task_list 最近のタスク一覧(結果の本文は含まない)
task_cancel 実行中のタスクをキャンセル(最大 100 件)
  • 同じワーカーに同じ input を 2 分以内に(タイミングにより最大約 4 分)送ると、既存のタスクが返されます。完了・キャンセル済みのタスクもそのまま返され、失敗したタスクだけが新しく作られます
  • キャンセルはワーカーに通知されません。 残りの配信試行が止まるだけで、すでに受け取ったワーカーからの以後の報告は 409 になります

ステータスの確認

状態 意味 変わるか
working 配信中、またはワーカーが処理中 変わる
completed ワーカーが完了を報告 最終
failed ワーカーの失敗報告、配信の失敗、または 24 時間経過 最終
cancelled キャンセル済み 最終

failed の理由は status_message に残ります。

原因 status_message の例
ワーカーが失敗を報告 ワーカーが送ったメッセージ(なければ error.message
再試行を使い切った The task could not be delivered to the worker after 6 attempts (no response within 15s).
即時失敗の応答 The task could not be delivered to the worker after 1 attempt (HTTP 401).
24 時間経過 Worker did not respond within 24 hours.

確認できる場所:

  • AItask_gettask_list。ワーカーの result要約されずにそのまま渡されます
  • Web実行履歴 タブ。期間(7・30・60 日、Free は 7 日)と状態で絞り込み、行をクリックすると入力・結果・エラー・配信が見られます。配信が最終的に失敗した場合、配信 に試行回数・最後の応答・理由が表示されます

制限事項

項目
ワーカー数 Free 1 個 / 有料プランは無制限
タスク数・同時実行 無制限(月間 API 呼び出し上限の範囲内)
期限 作成から 24 時間 — 過ぎると failed(1 時間ごとの確認のため最大約 25 時間)
履歴の保存 有料プランは最低 60 日 / Free はワーカー登録から 7 日後にワーカーと実行履歴をすべて削除
input のサイズ 100 KB
報告の本文 100 KB(status_message は 256 文字で切り捨て)
配信タイムアウト・再試行 15 秒・計 6 回、約 5 時間
署名シークレット再発行の猶予 48 時間
コールバックキーの再生成 以前のキーは即座に無効
API 呼び出しのカウント 成功したタスクツール呼び出し 1 回・受け付けられた報告 1 回がそれぞれ 1 回。配信・再試行は 0 回。上限を超えても報告は受け付けます
配信の保証 at-least-once(同じタスクが 2 回届くことがある)

個人情報について

  • ワーカーの resulterrorマスキングされずにそのまま AI との会話に渡されます
  • 3Min API は自由形式の JSON から個人情報を判別しないため、結果に必要以上の個人情報を含めないでください

トラブルシューティング

  • すべてのタスクがすぐ failed になる: 実行詳細の 配信 → 最後の応答 を確認してください。401 なら、署名シークレットの欄にコールバックキーを入れたか、再発行直後に以前のシークレットを消した可能性があります
  • タスクが working のまま: ワーカーが 2xx を返すだけで報告していません。ワーカーのログでステータス報告 API の応答コードを確認してください
  • 報告が 401 になる: tm_task_ で始まるコールバックキーか、再生成前のキーではないかを確認してください
  • 報告が 409 になる: すでに終了またはキャンセルされたタスクです。これ以上送る必要はありません
  • 報告が 413 になる: 本文が 100 KB を超えています。result を縮めて再送してください
  • 同じリクエストなのに新しいタスクができない: 2 分以内の同じ input は既存のタスクを返します。日付などを input に入れて区別してください