テスト&連携ガイド
概要
エンドポイント詳細ページでテスト開始をクリックすると開くページです。追加ツールなしでブラウザから直接APIコールをテストでき、協力者と共有すれば連携に必要な情報をすべて1か所で確認できます。
このページでのテストはサンドボックス環境のみで行われます。本番データには影響しないため、自由に試してください。
ページには2つのタブがあります:
- クイックスタート — APIキーで認証し、すぐにコールをテストします
- ガイド — オーナーと協力者のための連携リファレンス(ステップガイド、APIエンドポイント、ヘッダー、フィールド定義、コード例など)
このページへのアクセス方法
- エンドポイント詳細右サイドバー > テスト開始ボタン(サンドボックスタブ)
- 協力者も招待承諾後、自身のダッシュボードからアクセスできます
エンドポイント情報

- エンドポイント名と説明が表示されます
- 環境バッジ(サンドボックス)とバージョン情報が並んで表示されます
- クイックスタート / ガイドタブを切り替えます
クイックスタートタブ
認証
テストを開始するには、まずAPIキーで認証する必要があります。

- サンドボックスキー(
tm_test_で始まるもの)を入力欄に貼り付けて認証をクリックします - 2種類のキーが使用できます:
- デフォルトAPIキー — オーナーが直接テストする場合
- コラボレーションキー — 協力者が自身のキーでテストする場合

認証が完了すると入力欄が消え、ログアウトボタンが表示されます。別のキーでテストするには、ログアウトしてから再度認証してください。
試してみる

認証後、CRUDコール実行エリアが有効になります。メソッドを選択し、リクエストボディ(JSON)を入力して実行をクリックすると、すぐに結果が表示されます。
フルフローを一度にテストしたい場合は、以下の順序で行ってください:
CRUD全テストガイド
CREATE (POST) — リクエストボディにテストJSONを入力して実行します。レスポンスから
idをコピーしてください。次のステップで使います。READ — 単件取得 (GET) — レコードIDフィールドに
idを貼り付けて実行します。そのレコードの payload 全体が返されます。READ — 一覧取得 (GET list) — レコードIDなしで GET を呼び出すと、最近のレコードが新しい順に返ります。
limit(1〜30、デフォルト 10)とcursorでページネーションし、レスポンスのpagination.next_cursorを次回呼び出しのcursorに渡すと次のページを取得できます。READ — 検索 (GET search) — payload 内のキーワードでレコードを検索します。
q(必須、3〜200 文字)と任意のstart/end(未指定時は直近 30 日)、limit、cursorを使います。大文字小文字を区別しない部分一致で、カーソルページネーションを使用します。READ — ポーリング (GET poll) — 前回のポーリング以降に作成されたレコードを古い順に取得します。初回は何も渡さない(今から購読)か
sinceを使い、以降は直前のレスポンスのカーソルをそのまま返します。next_cursorはまだ残りがある合図なので即座に再呼び出しし、poll_cursorは追いついた合図なので保存して次の周期まで待ちます。UPDATE (PUT) — 同じ
idを入力し、変更したJSONをリクエストボディに入力します。これは完全置換なので、変更するフィールドだけでなく保持したいフィールドも含めてください。DELETE — 同じ
idを入力して実行します。その後、READを再度試してレコードが削除されたことを確認します。
権限チェック: コラボレーションキーでテストする場合、そのキーの権限で許可されたメソッドのみ実行できます。権限のないメソッドを呼び出すと403エラーが返されます。権限はコラボレーションキー > 権限で確認してください。
協力者Webhook

「試してみる」セクションの下部に、折りたたみ可能なWebhook設定エリアがあります。これはオーナーがダッシュボードで設定するWebhookとは別のもので、APIコーラーがリクエストヘッダーにWebhook情報を含めることで、指定したURLに処理結果を受信するためのものです。ここでこれらのヘッダーをテストできます。
- オーナーのWebhookとは独立して動作します
- 実際の連携では、Webhookヘッダーは直接APIコールコードに含めます
- 詳しいヘッダー名と実装方法はガイドタブのWebhook設定セクションをご覧ください
ガイドタブ
ガイドタブは、オーナーと協力者の両方が連携フロー全体と技術的な詳細を1か所で確認できるように構成されています。上部にロール別のステップガイド、その下に技術リファレンスが続きます。
はじめに — オーナー

エンドポイントを作成した方タブを選択すると、オーナーの視点からのステップが表示されます。
- エンドポイント作成 — API名を設定するだけでCRUDが自動作成されます。説明と必須フィールドは後から追加可能です
- サンドボックステスト&ログ確認 — クイックスタートタブでデフォルトAPIキーを使ってコールし、ダッシュボードのログでデータ受信を確認します
- コラボレーションキー作成&招待 — キーを作成し、詳細ページからメール招待を送信します
- 連携テスト — 協力者がサンドボックスで正しくコールしていることをログで確認します
- 本番デプロイ — 協力者のデプロイリクエストを承認するか、直接デプロイします。デプロイ後に協力者に通知されます
はじめに — 協力者

招待された方タブを選択すると、協力者の視点からのステップが表示されます。
- 招待を承諾 — 招待メールを確認し、ログイン後にダッシュボードで承諾します
- APIキーを確認 — エンドポイント詳細ページでサンドボックスAPIキー(
tm_test_)を確認します - 連携&テスト — クイックスタートタブでコールをテストし、ガイドタブの技術情報を参照して連携を構築します。202レスポンスを受信すれば、以降の処理はシステムが保証します
- デプロイリクエスト — テスト完了後、エンドポイント詳細ページからデプロイリクエストを提出します
- 本番環境に切り替え — オーナーがデプロイを完了すると通知されます。本番タブで本番APIキー(
tm_live_)を確認して適用します
APIエンドポイント

このエンドポイントで使用可能なAPIパスとメソッドを表示します。エンドポイント作成時に以下のメソッドが自動的に準備されます。
| メソッド | パス | 説明 |
|---|---|---|
| POST | /api/v1/data/{slug} |
新しいレコードを作成 |
| GET | /api/v1/data/{slug}/{record_id} |
IDでレコードを取得 |
| GET | /api/v1/data/{slug} |
最近のレコード一覧取得(cursorページネーション) |
| GET | /api/v1/data/{slug}/search |
payload テキスト検索(q, 任意の start/end; 最小 3 文字, カーソルページネーション) |
| GET | /api/v1/data/{slug}/poll |
前回のポーリング以降に作成されたレコードを古い順に取得(since または cursor, カーソルページネーション) |
| PUT | /api/v1/data/{slug}/{record_id} |
レコードを置換 |
| DELETE | /api/v1/data/{slug}/{record_id} |
レコードを削除 |
{slug}はエンドポイント作成時に自動的に割り当てられる一意の識別子です。実際の値はこのページで確認できます。
検索 (search) 呼び出しには q(3〜200 文字)が必須です。start / end(YYYY-MM-DD または RFC 3339)は任意で、未指定時は直近 30 日が自動適用されます。範囲の上限はありません。結果はカーソルページネーションで、次ページがある場合はレスポンスに pagination.next_cursor が含まれます。payload 全体に対して大文字小文字を区別しない部分一致で検索するため、数値や JSON キーの偶然の一致が発生する場合があります(例: 32 で検索すると 132 も一致)。検索は単件 GET / 一覧 GET と同じ read 権限で動作します。
ポーリング (poll) 呼び出しは created_at の昇順でレコードを進みます — 一覧・検索とは逆です。パラメータを何も渡さなければ今から購読し、since(YYYY-MM-DD または RFC 3339、すべて UTC — 2026-08-28 は JST の深夜ではなく UTC の深夜です)で開始時点を指定するか、cursor で継続します。since と cursor の同時指定は 400 です。limit は 1〜100(デフォルト 100)で、カーソルには含まれないためページごとに再送してください。レスポンスには 2 種類のカーソルのうち必ず 1 つだけが含まれます。next_cursor はまだ残りがある合図なので即座に再呼び出しし、poll_cursor は追いついた合図なので保存して次の周期まで待ちます。直近およそ 60 秒は除外されます。created_at はゲートウェイが発行する一方、実際の挿入はキュー経由の非同期のため、このマージンがないと到着前のレコードを飛ばしてウォーターマークが進んでしまいます。それらのレコードは次回のポーリングで届きます — 消失ではなく繰り延べです。リトライや再起動で同じレコードが再送されることがあるため、レコードの id を基準に冪等に処理してください。ポーリングは単件 GET / 一覧 GET / 検索 GET と同じ read 権限で動作します。
APIキー

APIコール時の認証に使用するキー情報です。
| 環境 | キープレフィックス | 用途 |
|---|---|---|
| サンドボックス | tm_test_ |
開発・テスト |
| 本番 | tm_live_ |
本番サービス |
本番APIキーは、デプロイ完了後にエンドポイント詳細ページで確認できます。デプロイ前は、本番キーでのコールは拒否されます。
リクエストヘッダー

APIコールに含めるHTTPヘッダーです。Content-TypeとAuthorizationは必須です。Webhookヘッダーは必要な場合のみ追加します。
| ヘッダー | 必須 | 説明 |
|---|---|---|
Content-Type |
必須 | application/json(POST/PUT用) |
Authorization |
必須 | Bearer {API_KEY}形式 |
X-Webhook-Callback |
任意 | コーラーWebhookを受信するURL |
X-Webhook-Auth |
任意 | Webhook認証値(例: Bearer token) |
X-Webhook-Auth-Header |
任意 | Webhook認証ヘッダーキー(デフォルト: Authorization) |
リクエストボディ

POST/PUTリクエストで送信するJSONボディに関する情報です。
- 形式: JSON(
application/json)· 最大100KB · UTF-8 - オーナーが必須フィールドを定義している場合、それらのフィールドを含める必要があります。必須フィールド以外の追加フィールドは自由に送信できます
- 必須フィールドが定義されていない場合、任意のJSONが受け入れられます
- リクエストは非同期で処理されます。即座に202レスポンスが返り、実際の保存とWebhook配信はバックグラウンドで行われます
レスポンス形式

各メソッドの成功レスポンスとエラーコードを表示します。
成功レスポンス:
- POST/PUT/DELETE →
202 Accepted(リクエスト受理、キューに追加) - GET(単件) →
200 OK(レコードを即座に返却) - GET(一覧) →
200 OK(ページネーション済みデータ + 次ページがあればnext_cursor) - GET(検索) →
200 OK(ページネーション済みデータ + 次ページがあればnext_cursor) - GET(ポーリング) →
200 OK(古い順のデータ +next_cursor/poll_cursorのうち必ず 1 つ)
エラーコード:
| コード | ステータス | 意味 |
|---|---|---|
| 400 | Bad Request | 不正なJSON、必須フィールドの欠如、無効なレコードID |
| 401 | Unauthorized | APIキー未設定または無効 |
| 403 | Forbidden | エンドポイント無効、サブスクリプションなし、権限不足 |
| 415 | Unsupported Media Type | Content-Typeがapplication/jsonでない |
| 429 | Too Many Requests | 月間使用量制限超過 |
| 5xx | Server Error | 一時的なサーバーエラー — リトライロジックを実装してください |
5xxエラーを受信した場合、リクエストはサーバーに到達していません。コードにリトライロジックを実装してください(例: 1秒 → 2秒 → 4秒バックオフ)。202レスポンスを受信した場合、以降の処理はシステムが保証します。
Webhook設定

処理結果を自動的に受信するためのコーラーWebhookの設定手順です。これはオーナーのダッシュボードWebhookとは別に、独立して動作します。
設定方法: APIコールに以下のヘッダーを含めます。
| ヘッダー | 必須 | 説明 |
|---|---|---|
X-Webhook-Callback |
必須 | Webhookを受信するURL |
X-Webhook-Auth |
任意 | 認証値(例: Bearer token) |
X-Webhook-Auth-Header |
任意 | 認証ヘッダーキー(デフォルト: Authorization) |
すべてのWebhookに付与するヘッダー:
| ヘッダー | 説明 |
|---|---|
X-3minapi-Record-Id |
レコードID。すべての配信試行で同一です — 重複判定に使用してください |
X-3minapi-Delivery-Attempt |
試行番号(1から開始) |
webhook-id |
レコード ID。X-3minapi-Record-Id と同じ値です |
webhook-timestamp |
署名した時刻(unix 秒)。試行のたびに作り直します |
webhook-signature |
HMAC-SHA256 署名。シークレット差し替え中は 2 つ届きます |
受信サーバー側の要件:
- 15秒以内に2xxを返してください。重い処理は自前のキューに渡し、まず応答してください
- 2xx は「成功した」ではなく「受け取った」という意味です。自分側の処理が失敗しても 2xx を返してください — 上流 API の拒否、自分側のバリデーションエラー、履行できない注文はいずれも該当します — その失敗は自分のシステムに記録してください。5xx は本来の意味の場合にだけ使ってください: 受信側自身、またはその依存先が一時的に停止していて、同じレコードを後で受け取れば成功しうる場合です。5xx を返すと同じレコードを下記のリトライスケジュールで再送するため、受信側はそのたびに同じ処理を実行することになります
- 同じ
X-3minapi-Record-Idが複数回届くことがあります。この値で処理済みかどうかを判断してください
リトライポリシー:
- 成功条件: 2xx ステータスコード — 配信を受け取ったことの確認であり、自分側の処理が成功したという意味ではありません
- 本番は合計6回試行 — 最初の配信1回 + リトライ5回(30秒・2分・10分・1時間・4時間、約5時間)。サンドボックスは合計4回試行 — 最初の配信1回 + リトライ3回(30秒・2分・10分、約12分)
- リトライ対象: 5xx(501・505 を除く)、429、タイムアウト、接続エラー。429 の
Retry-Afterは**「もっと待て」という要求としてのみ**反映され、既定の間隔より短くなることはなく、4 時間を超える値は無視します - リトライしない: 429以外のすべての4xx — 409も含みます(受信側が既に受け取ったものと解釈します)。設定を修正すれば次回から正常に配信されます
- すべて失敗しても、データは安全に保存されています — 保持期間(本番は最低60日、サンドボックスは30日)内であれば、ポーリングエンドポイントで後から取得できます。失敗した配信・再試行中の配信はログ画面の Webhook 配信で、レスポンス本文や試行履歴まで確認できます
- 配信をあきらめた時点で、エンドポイントのオーナーにメールでお知らせします(リトライを使い切った場合、またはリトライしない永続的なレスポンスの場合) — プランを問わず(無料プランも対象)お届けしますが、本番環境のオーナー Webhook の場合のみで、1 エンドポイントにつき 1 日 1 通までです。追送も復旧通知もありません。コラボレーター Webhook の失敗はメールしません。その URL はオーナーが変更できないためです
Webhook 署名の検証
送信するすべての Webhook に HMAC-SHA256 署名を付与しています。そのリクエストが本当に 3Min API から送られ、途中で内容が変わっていないことを確認できます。
検証は任意です。すでに Webhook を受け取っている場合、何もしなくてもそのまま動作します。有効にすると、受信 URL を知った第三者が偽のリクエストを送り、本物の配信を「処理済み」として捨てさせる攻撃を防げます。
暗号化ではありません。 本文はこれまでどおり平文で送られます。変わるのは、「この本文は 3Min API を出てから一文字も変わっていない」ことを証明する指紋がヘッダーに付く、という点だけです。
指紋は 3 つのパーツをつなげて作ります。
署名対象 = "{webhook-id}.{webhook-timestamp}.{リクエスト本文の原文}"
鍵 = シークレットから whsec_ を取り除き base64 デコードしたバイト列
署名 = base64( HMAC-SHA256(鍵, 署名対象) )
3 つのパーツは、それぞれ別のものを防ぎます。
| パーツ | 防ぐもの |
|---|---|
| リクエスト本文 | 途中で中身をすり替えること |
| webhook-timestamp | 過去にやり取りされた本物のリクエストをそのまま送り直すこと(リプレイ) |
| webhook-id | 他人のレコード ID を付けて送り、本物の配信を「処理済み」として捨てさせること |
シークレットの場所: ダッシュボード > エンドポイント詳細 > Webhook 署名シークレット。サンドボックスと本番で別々です。
ライブラリで検証する(推奨)
Standard Webhooks 仕様にそのまま準拠しているため、公式ライブラリを使えば数行で済みます。
| 言語 | パッケージ |
|---|---|
| Node.js / TypeScript | standardwebhooks (npm) |
| Python | standardwebhooks (pip) |
| PHP | standard-webhooks/standard-webhooks (composer) |
| Go | github.com/standard-webhooks/standard-webhooks/libraries/go |
| Ruby | standardwebhooks (gem) |
| Java / Kotlin | com.standardwebhooks:standardwebhooks |
| C# | StandardWebhooks (NuGet) |
| Rust | standardwebhooks (crates.io) |
| Elixir | standard_webhooks (hex) |
// npm i standardwebhooks
import { Webhook } from 'standardwebhooks';
import express from 'express';
const app = express();
// 서명은 우리가 보낸 바이트 그대로에 대해 계산됩니다.
// JSON으로 파싱한 뒤 다시 문자열로 만들면 반드시 실패합니다.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const wh = new Webhook(process.env.WEBHOOK_SIGNING_SECRET.replace('whsec_', ''));
try {
const payload = wh.verify(req.body, {
'webhook-id': req.header('webhook-id'),
'webhook-timestamp': req.header('webhook-timestamp'),
'webhook-signature': req.header('webhook-signature')
});
// 검증 통과 — payload를 처리하세요
res.sendStatus(200);
} catch {
res.sendStatus(401);
}
});
自分で実装する場合
- シークレットから
whsec_接頭辞を取り除き、残りを base64 デコードして鍵バイト列を得ます webhook-timestampが現在時刻の ±5 分以内か確認します(古いリクエストの再送を遮断)base64(HMAC_SHA256(鍵, "{webhook-id}.{webhook-timestamp}.{生のボディ}"))を計算しますwebhook-signatureを空白で分割し、v1,で始まる項目のいずれかが一致すれば通過です
注意点
- 生のバイト列で計算してください。 JSON をパースして文字列に戻すとキー順や空白が変わり、必ず失敗します。Express は
express.raw、Flask はrequest.get_data()、PHP はfile_get_contents('php://input')を使ってください - 署名は複数ある場合があります。 シークレット差し替え中は 2 つ届くため、最初の 1 つだけを見て失敗扱いにすると切り替え期間中すべて拒否されます
v1,以外の項目は無視してください。 将来別バージョンが追加されても安全に動作します==で比較しないでください。crypto.timingSafeEqual(Node)、hmac.compare_digest(Python)、hash_equals(PHP)のような一定時間比較を使ってください
シークレットの差し替え
シークレットの再発行はエンドポイントのオーナーのみが行え、漏洩したときの対処手段です — 定期的に回す値ではありません。再発行後 24 時間は新旧両方の署名が送信されるため、その間の任意のタイミングで受信サーバーを更新すれば配信は途切れません。24 時間を過ぎると新しい署名のみになります。
コラボレーターとして Webhook を受け取っている場合もシークレットを閲覧できます — 自分の Webhook も同じシークレットで署名されるためです。再発行のみがオーナー権限です。
コード例

curl、JavaScript、Pythonなど主要な言語でのAPIコールコードサンプルが提供されます。タブを切り替えて各言語の例を確認できます。実際のエンドポイントURLと必須ヘッダーが事前入力されているため、コピーしてそのまま使用できます。
APIリファレンスタブ

このエンドポイントの仕様を OpenAPI形式で一目で確認できる タブです。メソッドごとのカードにリクエストURL・ヘッダー・パス/クエリパラメータ・リクエストボディのスキーマ・レスポンス例まで含まれているので、外部ツールなしにこのページだけで連携仕様を把握できます。
- クイックスタートタブが「直接呼び出して確認」なら、APIリファレンスタブは 「仕様を見て連携コードを作成」 する用途です
- POST / GET(単件) / GET(一覧) / GET(検索) / GET(ポーリング) / PUT / DELETE がカード単位で分かれており、メソッドごとの違いを一目で比較できます
- レスポンス例は実際のレスポンスと同じJSON構造で表示されます — クライアントの型定義にそのまま活用できます
トラブルシューティング
- 「認証」をクリックしても何も起こらない: APIキーが
tm_test_(サンドボックスキー)で始まっているか確認してください。本番キー(tm_live_)はこのページでは使用できません - CREATE後にIDを失った: もう一度CREATEを実行して新しいレコードを生成し、テストを続けてください。以前のレコードのIDが必要な場合は、ダッシュボードのログページでコール履歴を確認してください
- 403エラーが出る: 使用しているコラボレーションキーにそのメソッドの権限がない可能性があります。コラボレーションキー > 権限で確認してください
- Webhookが届かない: Webhookサーバーは15秒以内にレスポンスを返す必要があります。公開アクセス可能でHTTPSを使用しているか確認してください。DiscordやSlackにはレート制限があり、短時間に大量のWebhookが発火するとブロックされる場合があります