POST /observations/search
cross-company observation search の request/response contract を説明します。
このページの内容9項目
POST /api/signal-foundry/observations/search は、company をまたいで observation を探索する endpoint です。結果は observation 単位ではなく company 単位に group されます。
この endpoint は保存しない cross-company evidence review 専用です。すでに 1 社が決まっている場合は、先に GET /companies/{companyId}/observations または sf company observations <companyId> --json を使います。保存済み List を作る前提なら sf list estimate -> discovery show/refine -> discovery materialize を使います。
契約サマリー
| Field | Value |
|---|---|
| Method | POST |
| Path | /api/signal-foundry/observations/search |
| Auth | production は API key 必須 |
| Usage | request usage と heavy usage に count |
| Credit | data credit は消費しない |
| CLI | sf observations search <query> --json |
| Next | hit company を profile / observations / list に落とす |
heavy endpoint です。request usage と heavy usage に count され、429 rate_limit_exceeded では Retry-After に従ってください。
リクエスト
curl -s -X POST \
-H "Authorization: Bearer <SIGNAL_FOUNDRY_API_KEY>" \
-H "content-type: application/json" \
"https://signal-foundry.app/api/signal-foundry/observations/search" \
-d '{
"query": "生成AI CRM",
"filters": {
"market_segments": ["prime"],
"sources": ["edinet"]
},
"limit": 10,
"observations_per_company": 3
}'
リクエストボディ
{
"query": "AI workflow automation",
"filters": {
"company_ids": ["jpx_7203"],
"has_website": true,
"industries": ["輸送用機器"],
"market_segments": ["prime"],
"observation_subtypes": ["technology_adoption"],
"observation_types": ["corporate_profile"],
"sources": ["company_website"],
"technologies": ["HubSpot"],
"website_domains": ["global.toyota"]
},
"limit": 20,
"observations_per_company": 5,
"scan_limit": 5000
}
フィルタ
company_idshas_websiteindustriesmarket_segmentsobservation_subtypesobservation_typessourcestechnologieswebsite_domains
filters.technologies は profile / evidence 内の技術語にも使えます。generative_ai、genai、llm、ai_agent は EDINET theme alias として扱われ、query が空でも 生成AI、LLM、AIエージェント の evidence search に展開されます。alias を source が合わない filter と組み合わせた場合、例えば sources: ["company_website"] では EDINET 本文検索には進みません。
会社名、証券コード、法人番号が主語の場合は、まず GET /companies / sf companies search ... --json で company_id に解決してください。解決済みの会社だけに絞りたい場合は filters.company_ids を使います。
検索処理
この endpoint は 2 段階で絞ります。
- SQL 側で
company_ids / observation_types / observation_subtypes / sourcesを前処理 - app 側で
has_website / industries / market_segments / website_domains / technologiesと relevance を適用
query は whitespace で tokenize され、observation summary/type/subtype/source に加えて evidence、company 名、industry、market segment、website 情報にも照合されます。token はすべて match する必要があります。
レスポンス
まず見る key:
results[].company.company_idresults[].company.display_nameresults[].matched_observations[].observation_idresults[].matched_observations[].summaryresults[].matched_observations[].evidenceresults[].score.max_relevancemeta.returned_companiesmeta.matched_observationsmeta.scan_limitmeta.scan_limit_requestedmeta.technology_aliases
matched_observations[] は company ごとの代表観測で、observations_per_company を上限に返ります。
scan_limit の既定値は 5000、request schema 上の最大値は 10000 です。API key request では abuse guardrail のため server 側 cap がさらに適用される場合があります。response の meta.scan_limit は server が実際に適用した値、meta.scan_limit_requested は client が送った値です。
{
"results": [
{
"company": {
"company_id": "jpx_5574",
"display_name": "ABEJA",
"market_segment": "growth"
},
"matched_observations": [
{
"observation_id": "obs_...",
"type": "corporate_profile",
"subtype": "strategy",
"source": "edinet",
"summary": "生成AIに関する記載の要約",
"evidence": {},
"match_relevance": 8,
"confidence": 0.9,
"observed_at": "2026-04-30T00:00:00.000Z"
}
],
"score": {
"matched_observation_count": 1,
"max_confidence": 0.9,
"max_relevance": 8
}
}
],
"meta": {
"returned_companies": 1,
"matched_observations": 1,
"scan_limit": 5000,
"scan_limit_requested": 5000,
"technology_aliases": {
"applied": true,
"aliased": [
{
"input": "generative_ai",
"query": "生成AI"
}
],
"effective_query": "生成AI",
"passthrough": []
}
}
}
この HTTP response では、cross-company results は results[] に入り、会社は results[].company、代表 observation は results[].matched_observations[]、source coverage は meta.source_search で確認します。
CLI equivalent
sf observations search "生成AI CRM" \ --source edinet \ --market-segment prime \ --limit 10 \ --observations-per-company 3 \ --json
hit した company は、次に 1 社 endpoint へ落とします。
sf company profile <companyId> --json sf company observations <companyId> --limit 5 --json
エラー
| Code | 復旧 |
|---|---|
400 invalid_request | query / filters / limit / observations_per_company / scan_limit を schema に合わせる |
401 invalid_api_key | API key を再発行し、CLI なら sf auth setup をやり直す |
429 rate_limit_exceeded | Retry-After まで待つ。heavy usage cap に当たっている可能性がある |
500 observation_query_failed | 時間を置いて再実行し、再現する場合は query と filters を添えて問い合わせる |
500 edinet_evidence_query_failed | sources から edinet を外すか、短い query で再実行する |
復旧方法
low-hit の場合:
- 長い自然文を 1-3 token の theme 語に短くする。
observation_types/sources/technologiesを一度外す。- 構造条件は
industries/market_segmentsに分ける。 - 固有名詞が混ざっている場合は、先に
sf companies search <query> --jsonでcompany_idを解決し、filters.company_idsに入れる。 - 証券コードや
company_idが分かっている場合は、sf company observations <companyId> --jsonに切り替える。
hit が多すぎる場合:
market_segments/industries/sourcesを追加する。observations_per_companyを下げる。- 保存したい会社群なら、
sf list estimate "<criteria>" --jsonに進んで credit boundary を確認する。
observations-search は保存しない横断探索と evidence review のための endpoint です。保存済み List を作る job では、list estimate -> discovery show/refine -> discovery materialize を使ってください。