測試與整合指南
概述
這是在端點詳細頁面點擊立即測試後開啟的頁面。您可以直接在瀏覽器中測試 API 呼叫,無需任何額外工具,還可以與協作者分享,讓他們在一個地方找到整合所需的所有資訊。
此頁面的測試僅在沙箱環境中進行。不會影響正式環境資料,請放心實驗。
頁面有兩個分頁:
- 快速開始 — 使用 API 金鑰認證並立即測試呼叫
- 指南 — 面向所有者和協作者的整合參考(分步指南、API 端點、標頭、欄位定義、程式碼範例等)
如何進入
- 端點詳細右側邊欄 > 立即測試 按鈕(沙箱環境分頁)
- 協作者接受邀請後也可以從自己的儀表板存取
端點資訊

- 顯示端點名稱和描述
- 旁邊顯示環境標籤(沙箱環境)和版本資訊
- 在 快速開始 / 指南 分頁之間切換
快速開始分頁
認證
要開始測試,需要先使用 API 金鑰進行認證。


認證後,輸入框消失,顯示 退出 按鈕。要使用其他金鑰測試,先退出再重新認證。
試一試

認證後,CRUD 呼叫執行區域被啟用。選擇方法,輸入請求主體(JSON),點擊 Execute 即可立即看到結果。
如果想一次性測試完整流程,請按以下順序進行:
完整 CRUD 測試指南
CREATE (POST) — 在請求主體中輸入測試 JSON 並執行。從回應中複製
id——後續步驟需要用到。READ — 單筆查詢 (GET) — 將
id貼到 Record ID 欄位並執行。該記錄的完整 payload 會被回傳。READ — 清單查詢 (GET list) — 不帶 Record 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 設定部分
指南分頁
指南分頁的結構讓所有者和協作者都可以在一個地方查看完整的整合流程和技術細節。頂部是角色專屬的分步指南,下方是技術參考。
入門 — 所有者

選擇 我建立了端點 分頁,從所有者的視角查看步驟。
- 建立端點 — 只需設定 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 是 UTC 零點而非本地零點)指定起點,或用 cursor 續傳;since 與 cursor 同時傳入回傳 400。limit 為 1-100(預設 100),且不包含在游標中,因此每頁都要重新傳。每次回應只會包含兩種游標中的一種: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中恰好一個)
錯誤代碼:
| 代碼 | 狀態 | 含義 |
|---|---|---|
| 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 簽章。更換密鑰期間會收到兩個 |
接收方需要遵守的約定:
- 請在 15 秒內回傳 2xx。將繁重處理交給你自己的佇列,先回應
- 2xx 表示「我收到了」,而不是「處理成功了」。即使你這邊的處理失敗也要回傳 2xx —— 上游呼叫被拒、你這邊的驗證錯誤、無法履行的訂單都算 —— 並把該失敗記錄在你自己的系統裡。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,每個端點每天最多一封。沒有後續郵件,也沒有復原通知。協作者 Webhook 的失敗不會寄送郵件,因為端點所有者無法變更該 URL
驗證 Webhook 簽章
我們傳送的每個 Webhook 都帶有 HMAC-SHA256 簽章,你可以據此確認請求確實來自 3Min API,且在傳輸途中未遭更動。
驗證是選用的——如果你已在接收 Webhook,無需任何變更即可繼續正常運作。啟用後可防止得知你接收 URL 的人送出偽造請求,進而讓你的伺服器把真正的投遞當成「已處理」而丟棄。
這不是加密。 內容仍與以往一樣以明文傳送。改變的只是:請求標頭中多了一枚指紋,用來證明「這份內容自離開 3Min API 後一個字元都沒變過」。
指紋由三個部分拼接而成。
簽章對象 = "{webhook-id}.{webhook-timestamp}.{請求內容原文}"
金鑰 = 去掉 whsec_ 前綴後再做 base64 解碼得到的位元組
簽章 = base64( HMAC-SHA256(金鑰, 簽章對象) )
這三個部分各自防範不同的問題。
| 部分 | 防範什麼 |
|---|---|
| 請求內容 | 在傳輸途中掉包、竄改內容 |
| 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') - 簽章可能不只一個。 更換密鑰期間會收到兩個,只檢查第一個就判定失敗會導致整個過渡期全部遭拒
- 忽略非
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,部分可能會被攔截