要用 DocuSign API 按自訂欄位值搜尋信封,調用 Envelopes: listStatusChanges 端點(GET /restapi/v2.1/accounts/{accountId}/envelopes),帶上格式為 欄位名=值 的 custom_field 查詢參數,並同時提供 DocuSign 在每次信封搜尋中都要求的日期範圍參數。例如,custom_field=Region=West 返回名為 Region 的信封自訂欄位值為 West 的信封;custom_field=Region=%25West%25(即 %West% 的 URL 編碼形式)則比對值中只要包含 "West" 的信封。custom_field 正是為這項任務設計的專用篩選器,遠比把某個日期範圍內的所有信封全部拉回來、再在自己的程式碼裡逐個比對要高效。
動手之前有一點必須先知道:舊的 Search Folders 端點(GET /restapi/v2.1/accounts/{accountId}/search_folders/{searchFolderId})在 API v2.1 中已被標記為棄用。新的整合應基於 Envelopes: listStatusChanges 提供的 custom_field、search_text 和日期篩選器來構建信封搜尋。本文會完整走一遍流程:自訂欄位如何寫入信封、請求本身、回應處理、萬用字元、分頁,以及最容易讓首次嘗試出錯的失敗模式。
簡要答案:一個 GET 請求加兩個篩選條件
最小可用請求需要三樣東西:端點、一個 custom_field 篩選條件,以及 from_date(DocuSign 的信封搜尋文件註明,from_date 和 to_date 是每次信封搜尋操作的必填參數)。以下是 cURL 形式的請求:
```bash
curl -X GET "https://demo.docusign.net/restapi/v2.1/accounts/{accountId}/envelopes" \
-H "Authorization: Bearer {accessToken}" \
-H "Accept: application/json" \
--get \
--data-urlencode "custom_field=Region=West" \
--data-urlencode "from_date=2026-07-01T00:00:00Z" \
--data-urlencode "status=completed"
```
這個 URL 裡有三個細節值得注意:
- 值裡面含有等號。
custom_field=Region=West必須正確編碼,讓第二個=在查詢字串中保留下來。像上面那樣使用--data-urlencode,或者手寫編碼後的字串custom_field=Region%3DWest,都可以。 - 日期應採用帶明確時區偏移的 ISO 8601 格式。 DocuSign 建議使用
2026-07-01T00:00:00Z這類明確偏移;不帶偏移時會按伺服器時區解釋,你的時間窗口會被悄悄挪動。 status可選但很有用。 它接受逗號分隔的當前狀態列表,如completed、sent、delivered、declined或voided,any則比對所有狀態。
回應是一個 JSON 物件,其 envelopes 陣列包含比對到的信封摘要,含 envelopeId、status、emailSubject。如果摘要裡沒有你需要的全部資訊,可以對單個信封跟進調用 GET /restapi/v2.1/accounts/{accountId}/envelopes/{envelopeId}/custom_fields,它會返回該信封的自訂欄位,含 fieldId、name、value。
如果你還在熟悉身份驗證、整合金鑰和 demo 環境這些基礎,建議先把它們逐一跑通,再把本文的寫法接入正式環境的程式碼。
能搜的前提:先搞懂信封自訂欄位怎麼運作
搜不到從未存進去的東西。在 DocuSign 中,信封自訂欄位是掛在信封本身的元數據,不屬於某個文件或某個簽署人。它分兩種:文字自訂欄位(發送人手動輸入或透過 API 設定的自由文字)和清單自訂欄位(從預設清單中選擇的值)。通常由管理員在帳戶層級定義,再在建立或發送信封時填上具體值。
透過 API 建立信封時,在 customFields 物件裡設定它們:
```json
{
"status": "sent",
"emailSubject": "Master Services Agreement",
"customFields": {
"textCustomFields": [
{
"name": "ClientID",
"value": "CLI-12345",
"show": "true",
"required": "false"
}
]
}
}
```
這對 ClientID: CLI-12345,就是之後 custom_field=ClientID=CLI-12345 要比對的內容。這個設計帶來兩個實際影響:
- 一致性是你自己的責任。 搜尋比對的是發送人和整合實際寫入的內容。一個系統寫
CLI-12345,另一個寫cli_12345,只有嚴格的命名紀律才能保證搜尋可靠。把規範落在整合程式碼裡,而不是寄託在人的記性上。 - 信封自訂欄位不同於 tab(文件上的表單欄位)。 簽署人在文件欄位裡填的值,
custom_field是篩選不到的。要查這些值,需要匯出信封的表單數據後在本地比對。
另外注意,文字自訂欄位的值上限為 100 個字元,把它們當作索引鍵(ID、區域代碼、案件編號)來用,而不是自由文字儲存。
分步構建請求
下面是多數團隊實際會用的完整流程——一個基於 requests 的 Python 函數:
```python
import requests
def search_envelopes_by_custom_field(access_token, base_url, account_id,
field_name, field_value,
from_date, to_date=None):
url = f"{base_url}/restapi/v2.1/accounts/{account_id}/envelopes"
params = {
"custom_field": f"{field_name}={field_value}",
"from_date": from_date,
}
if to_date:
params["to_date"] = to_date
response = requests.get(
url,
headers={
"Authorization": f"Bearer {access_token}",
"Accept": "application/json",
},
params=params,
)
response.raise_for_status()
return response.json()["envelopes"]
results = search_envelopes_by_custom_field(
access_token=TOKEN,
base_url="https://demo.docusign.net",
account_id=ACCOUNT_ID,
field_name="ClientID",
field_value="CLI-12345",
from_date="2026-01-01T00:00:00Z",
)
for env in results:
print(env["envelopeId"], env["status"], env.get("emailSubject"))
```
因為 requests 會自動對參數做 URL 編碼,custom_field=ClientID=CLI-12345 中內嵌的 = 會被妥善處理。如果你用其他語言手工拼 URL,記得明確編碼(ClientID%3DCLI-12345)。
對比對精度要求高時,建議加一道客戶端校驗:遍歷返回的信封,在信封詳情裡確認自訂欄位的名稱和值完全相符之後,再據此採取動作。這能防住兩種意外:使用萬用字元時的部分比對誤傷,以及歷史信封上的欄位名漂移。
進一步篩選:狀態、日期範圍、資料夾與分頁
單一篩選條件很少對應真實的業務問題。Envelopes: listStatusChanges 支援多種參數組合,可以乾淨地對應到常見場景:
關於這些配套參數的說明:
from_date/to_date限定信封狀態發生變化的日期範圍。除非你改傳envelope_ids或transaction_ids,否則from_date是必填的。status與from_to_status的區別:status按信封的當前狀態篩選;from_to_status限定你關心的是窗口內的哪一次狀態變更。邏輯上不可能成立的組合(例如用delivered限定詞搭配當前狀態created)會在不查資料庫的情況下直接返回空列表——所以一個令人困惑的空結果,有時是邏輯錯誤,而不是數據缺失。- 資料夾範圍:
folder_ids和folder_types把搜尋限制在completed、draft、recyclebin等邏輯資料夾內。 - 用戶範圍:
user_id或user_filter把結果收窄到某個特定用戶作為發送人或收件人的信封。 - 分頁:用
count(每次調用返回的條數)配合start_position(起始的零基索引)翻頁遍歷大結果集,而不是一次請求全部。 - 裁剪回應內容:
exclude參數可以在不需要時把收件人或 PowerForm 數據等類別從回應中剔除。
如果你在評估一個重度依賴 API 的整合的總體成本,API 套餐和限額通常的構成方式值得單獨研究,再據此規劃調用量。
精確比對、萬用字元還是寬泛文字搜尋:選對篩選器
DocuSign 提供三種機制,選錯是「我的搜尋沒反應」最常見的原因:
萬用字元形式是最容易被忽略的:百分號包在值的兩側,手工拼查詢字串時要 URL 編碼為 %25。custom_field=ApplicationId=%25DocuSign%25 能比對 ApplicationId 值中任意位置包含 "DocuSign" 的信封。
代價是精度。search_text 是最鈍的工具:搜一個客戶 ID,會連帶命中主題、收件人電郵或郵件正文裡碰巧含有這個字串的所有信封。把 search_text 留給「幫我找那個信封」式的互動功能;在自動化工作流裡,凡是驅動下游邏輯的精確鍵,都用 custom_field。
常見錯誤與調用前排查清單
當自訂欄位搜尋什麼都返回不了、或返回了錯誤結果時,先過一遍這份清單,再懷疑 API:
from_date存在且覆蓋該信封。 信封可能比你的窗口更舊,或者缺失的時區偏移悄悄挪動了邊界。- 欄位名完全相符。 自訂欄位名是帳戶層級定義的大小寫敏感字串;
ClientID和ClientId是兩個不同的欄位。 - 值的編碼正確。 內嵌的
=需要%3D,字面量%萬用字元需要%25。 - 狀態組合在邏輯上成立。 檢查當前
status值能否與你的日期範圍和任何from_to_status限定詞共存。 - 該欄位是信封自訂欄位,不是文件 tab。 簽署人填寫的 tab 值對
custom_field不可見;這類值要匯出表單數據後在客戶端篩選。 - 帳戶沒搞錯。 多帳戶環境中,經常出現搜尋的是帳戶 A、而信封在帳戶 B 的情況。
- 存取權杖有效且未過期。 搜尋調用返回
401幾乎總是 OAuth 過期而非查詢問題;400則指向參數格式錯誤。
對於要把已簽署協議從 DocuSign 歸檔留存的團隊,有一點要提醒:搜尋只是留存策略的一半,另一半是可靠的匯出與本地備份機制,兩者缺一不可。
規模化建議:高流量場景下推送優於輪詢
搜尋是拉取模式,而定時輪詢在大多數調用沒有新結果時會白白消耗 API 額度。對於需要對信封事件做出反應的工作流,例如「客戶 X 的合約一完成就更新 CRM」,DocuSign Connect webhook 會在事件發生時把狀態更新推送到你的端點。一種常見的混合設計是:webhook 作為主觸發器,custom_field 搜尋作為對賬路徑——webhook 處理日常流程,每晚一次的搜尋掃描兜住任何因事件遺漏而落下的信封。這種掃描同時還兼任審計工具,因為它從源數據重新推導出「每個客戶有多少信封在待簽署」的視圖。
如果你對信封數據的需求已經從搜尋走向更完整的合約智能,那已經是另一個層面的議題,值得單獨評估。而如果你選型電子簽署平台時最看重開發者體驗,各平台如何處理本文這類整合工作,值得逐一比較後再定。
用 Nota Sign 構建可搜尋的簽署工作流
靠元數據追信封,背後是更深一層的需求:你的協議從建立那天起,就應該是可檢索的結構化數據。整合團隊帶著這種「檢索優先」的設計訴求找到的,正是 FaDaDa(法大大)旗下的全球電子簽署平台 Nota Sign。平台支援 100 多個國家和地區的簽署,其區域數據中心讓亞太地區的簽署流量貼近它所服務的交易對手。
如果你的路線圖包含圍繞可搜尋、可篩選的信封數據重建協議流水線,歡迎透過 Nota Sign 聯絡頁面 告訴我們你的整合需求。團隊會圍繞你的業務量、覆蓋地區,以及信封數據需要饋入的系統來界定討論範圍。








