入札監視
地域、業種タグ、キーワード、金額範囲などのフィルターに基づき、新規案件を自動配信 — Pull API+メールダイジェスト+Webhook。
概念
すべてのエンドポイントで登場する4つの用語:
- Tender — ポータル(NEN、VVZ、E-ZAK、TenderArena など)からの個別の案件。数値IDで識別されます。
- Filter — 保存された条件セット(地域、業種、キーワード、金額)。新しい案件が条件を満たすと、マッチが生成されます。
- Match — フィルターに合致した新規案件。(tender × filter)の紐付け+タイムスタンプ+ステータス(監視中 / 非表示 / 既読)を表します。
- Taxonomy — 地域(NUTS)、業種(industryタグ)、CPVコードのコードリスト。案件の分類に使用します。
クイックスタート
フィルターの設定方法は2通りあります。結果はいずれも同じであり、フィルターはいつでもどちらの方法でも編集可能です。
curl -H "X-Api-Key: mrw_live_…" \ "https://veritra.io/api/v2/leads/tenders/search?qText=rekonstrukce%20mostu&limit=5"
上部はアドホック検索です。継続的なモニタリング(条件に合致する新規案件の通知)を希望する場合は、フィルター+Webhook/メールダイジェストをご利用ください — 後述を参照。
案件検索(アドホック)
すべてのアクティブな入札案件を横断的に一度だけ検索する場合に使用します。保存済みフィルターは使用せず、パラメーターはクエリ文字列で直接指定します。
/api/v2/leads/tenders/searchクエリパラメーター
| パラメータ | 種別 | 説明 |
|---|---|---|
| qText* | string | 検索テキスト(title + description の全文検索)。 |
| regions | string | NUTSリーフコード CSV形式(CZ010,CZ020)。 |
| cpvPrefixes | string | CPVプレフィックス CSV形式(45,452)。 |
| industryTags | string | 業種タグID CSV形式(con_buildings,it_development)。 |
| minValue | number | 最小推定価格(CZK)。価格のない入札も通過します。 |
| maxValue | number | 最大推定価格(CZK)。価格のない入札も通過します。 |
| deadlineFrom | string (YYYY-MM-DD) | 提出期限 >= YYYY-MM-DD。 |
| deadlineTo | string (YYYY-MM-DD) | 提出期限 <= YYYY-MM-DD。 |
| sort | "newest" | "deadline" | "value" | 並び順: newest(デフォルト)、deadline(昇順)、value(降順)。 |
| limit | number | 取得件数(最大1,000件、デフォルト:50件)。1,000件超の場合はnextCursorページネーションまたは/matches/exportをご利用ください。 |
| cursor | string | 前ページのキーセットカーソル(pagination.nextCursor)。 |
例
curl -H "X-Api-Key: mrw_live_…" \ "https://veritra.io/api/v2/leads/tenders/search?qText=rekonstrukce®ions=CZ010,CZ020&minValue=500000&limit=10"
/api/v2/leads/tenders/:idレスポンス:id、title、description、estimatedValue、deadlineAt、contractingAuthority、documents[]、starred、excluded フィールドを持つ data オブジェクト。
/api/v2/leads/tenders/:id/emailリクエストボディに recipientEmail を含めることで、別のメールアドレスへ転送できます。デフォルトは user.email です。
/api/v2/leads/documents/previewクエリ:?url=:original&kind=docx|xlsx。許可ホスト:NEN、E-ZAK、Tender Arena、Gemin、ProfilZadavatele。
GET /api/v2/leads/documents/preview?url=https://nen.nipez.cz/…/Vyzva.docx&kind=docx → 302 Location: https://rwx-storage…/Tendero/doc-cache-v8/<hash>.html (signed, TTL 10 min)
カタログ・オートコンプリート(公開、認証不要)
UIドロップダウンおよびフィルター作成用。サーバーサイドで1時間キャッシュ。公開エンドポイントのため認証不要。
/api/v2/leads/zadavatele?q=praha/api/v2/leads/countries/api/v2/leads/regions?country=CZ/api/v2/leads/regions/catalog?country=CZ&locale=cs/api/v2/leads/taxonomy/industry/api/v2/leads/taxonomy/cpvフィルタリング可能な項目と許容値
フィルターは以下のフィールドで構成されます。`name` を除きすべて任意項目です。空フィールド = 当該ディメンションに制限なし。
regions string[]
指定国のNUTSリージョン(?country=CZ)。ロケールごとのラベル付き。
CZČeská republikaSKSlovenskoPLPolskoDENěmeckoATRakouskoFRFrancieESŠpanělskoITItálieNLNizozemskoBEBelgiePTPortugalskoSEŠvédskoFIFinskoDKDánskoNONorskoIEIrskoGRŘeckoRORumunskoBGBulharskoHUMaďarskoHRChorvatskoSISlovinskoLTLitvaLVLotyšskoEEEstonskoLULucemburskoCYKyprMTMaltaCHŠvýcarskoISIslandMKSeverní MakedonieGBVelká BritánieJPJaponsko特定国のNUTSツリー全体を取得するには、以下を使用してください:
GET /api/v2/leads/regions/catalog?country=CZ&locale=cs GET /api/v2/leads/regions/catalog?country=DE&locale=de GET /api/v2/leads/regions/catalog?country=FR&locale=en
例:CZ の NUTS-3 コード(州)— 展開 ▸
CZ010Hlavní město PrahaCZ020Středočeský krajCZ031Jihočeský krajCZ032Plzeňský krajCZ041Karlovarský krajCZ042Ústecký krajCZ051Liberecký krajCZ052Královéhradecký krajCZ053Pardubický krajCZ063Kraj VysočinaCZ064Jihomoravský krajCZ071Olomoucký krajCZ072Zlínský krajCZ080Moravskoslezský krajindustryTags string[] 推奨
マルチタグによる業種分類。案件には複数のタグを付与できます(例:改修工事の場合「stav_pozemni」+「stav_remesla」)。指定したタグのうち少なくとも1つに一致する案件をフィルタリングします(JSON_OVERLAPS)。
CPVよりindustryTagsを優先すべき理由: 当社のindustryTagsは、案件名・説明のLLM分類、CPVマッピング、正規表現ヒントを組み合わせて生成されます。CPVコードの割り当てが不正確な発注者の案件も適切に捕捉できます。CPVフィルターは精度が高い反面、発注者の規律に依存しており、チェコ共和国ではその水準が低い傾向にあります。
con_buildingsPozemní stavby a rekonstrukce budovcon_civilInženýrské stavby (silnice, mosty, voda)con_tradesStavební řemesla a dílčí prácecon_energy_efficiencyEnergetické úspory a OZEcon_materialsStavební materiáldes_documentationProjektová dokumentace a studiedes_supervision_ohsTechnický dozor a BOZPdes_surveyingGeodézie a pozemkové úpravyit_developmentVývoj SW a integraceit_licensingSW licence a předplatnéit_hardwareHW a infrastrukturait_cybersecurityKybernetická bezpečnostit_data_aiData, analytika, AI/MLtelecom_internetTelekomunikace, internet, mobilníprof_marketingMarketing, PR, reklamaprof_legalPrávní službyprof_accountingÚčetnictví, dotace, auditprof_hrHR, náborprof_translationPřeklady a tlumočeníprof_insurancePojištění a finančníops_cleaningÚklidové službyops_securityOstraha a recepčníops_maintenanceÚdržba a servis zařízeníops_wasteOdpadové hospodářstvíops_facilitySpráva nemovitostícat_cateringStravování, cateringcat_accommodationUbytování a konferencecat_foodPotraviny a nápojetrans_transportPřeprava cestujících a nákladutrans_vehiclesVozidla, díly, leasinghealth_pharmaLéčiva a farmahealth_devicesZdravotnické přístroje a materiálhealth_careZdravotní a sociální péčegoods_furnitureNábytek a vybavení interiérůgoods_clothingOděvy, OOPP, uniformygoods_electricalElektromateriálgoods_machineryPrůmyslové strojeenergy_fuelsPohonné hmoty a palivaenergy_power_heatElektřina a teploenergy_waterVodárenstvínat_forestryLesní hospodářstvínat_greeneryÚdržba zeleně a zahradnictvínat_agricultureZemědělstvídefense_safetyHasiči, vojsko, obranasci_labLaboratorní a měřicí vybavenísci_researchVýzkum a vývojedu_trainingVzdělávání a školenículture_mediaKultura, knihy, médiacategories string[] 精度低
任意の長さのCPV(共通調達語彙)プレフィックス — `LIKE 'prefix%'` によるマッチング。例:「45」ですべての建設部門、「4523」で土木工事のみ、「45316110」で街路照明のみに一致します。
03農業・林業・漁業09燃料・エネルギー15食品・飲料18衣類・履物・個人用保護具22印刷物・書籍30事務機器・IT機器31電気機械・ケーブル・照明器具32ラジオ・テレビ・通信機器33医療機器・医薬品34車両・輸送機器35セキュリティ・消防・防衛技術38実験・計測機器39家具・インテリア設備42産業機械44建設資材・構造物45建設工事48ソフトウェア・ライセンス50修理・保守55飲食・宿泊60輸送・運送サービス64郵便・通信サービス65公共サービス(電気・水道)66金融・保険サービス70不動産サービス・建物管理71建築・設計・エンジニアリングサービス72ITサービス(開発・統合・サポート)73研究・開発75行政・防衛77農業・林業・園芸サービス79ビジネスサービス(法律・会計・HR・マーケティング)80教育・研修85医療・社会福祉90廃棄物・環境・清掃92文化・スポーツ・レクリエーション98その他の住民向けサービス完全なカタログ(9,454コード)は/docs/leads/cpv でご確認いただけます — 部門別に検索・グループ化されています。
keywords string[]
案件名および説明文に対するLIKEマッチング。大文字・小文字を区別しません。項目間はOR条件。industryTags/CPVでは捕捉できない場合(例:テキスト中の特定の案件種別)の補完手段として有効です。
"keywords": ["rekonstrukce"、"VO"、"osvětlení"、"MŠ"]
minValue / maxValue number | null
案件の推定価格(チェココルナ)の範囲。minValueのみ、maxValueのみ、または両方を指定できます。
emailDigest boolean
trueに設定すると、このフィルターの新規マッチの概要メールが1日1回(UTC 5:00)送信されます。デフォルトはtrueです。フィルターの編集により無効化できます。Webhookはアカウントレベルで個別に設定します(以下のセクションを参照)。
name string · active boolean
`name` — 最大120文字、必須。`active` — falseにすると、フィルターがcronで実行されません(新規マッチ、ダイジェスト、Webhookなし)。削除せずに一時停止できます。
フィルタリングロジック
フィールドは以下のように組み合わされます:
MATCH = (発注者.NUTS3 ∈ expand(regions))
AND (minValue ≤ estimatedValue ≤ maxValue または estimatedValueがnullまたは0)
AND (industry_or_cpv または keyword_match)
# expand(regions): NUTSコードはNUTS 3のリーフノードに展開されます
# (CZ → 14州、CZ01 → CZ010、CZ010 → CZ010)。
industry_or_cpv:
industryTags指定あり → JSON_OVERLAPS(industryTags, tender.industryTags)
それ以外でcategories指定あり → tender.cpvCode LIKE ANY (categories + "%")
それ以外 → false (業種フィルターなし)
keyword_match:
keywords指定あり → tender.title または description LIKE ANY (%kw%)
それ以外 → false
# industryTags / categories / keywords をいずれも指定しない場合、
# regionsおよび価格範囲を満たすすべての案件が返されます。industryTagsはcategoriesより優先されます — 両方指定した場合、industryTagsのみが使用されます(categoriesは無視されます)。keywordsはindustry_or_cpvとOR条件として独立して機能します。
フィルター管理エンドポイント
フィルターの管理には管理キーを使用してください(mrw_live_…)。独立したレート制限を持ち、LEADSクレジットを消費しないため、フィルターの管理は毎日の案件取得に影響しません。
/api/v2/leads/filters/api/v2/leads/filters/api/v2/leads/filters/:id/api/v2/leads/filters/:id/api/v2/leads/filters/:id/api/v2/leads/filters/:id/matches/export?format=csv|xlsx|json&view=all|starred|excludedボディパラメータ(POST / PUT)— 共通
| パラメータ | 種別 | 説明 |
|---|---|---|
| name* | string | フィルター名(最大120文字) |
| regions | string[] | NUTSコード(例:`CZ010`)。任意のレベルを混在可。空の配列 = 全地域。 |
| industryTags | string[] | 推奨パス。当社タクソノミーのタグID(例:'stav_pozemni'、'it_vyvoj')。マルチタグ — 項目間はOR。 |
| categories | string[] | 任意の長さのCPVプレフィックス(例:'45'、'4523'、'45316110')。industryTagsより精度は低め。 |
| keywords | string[] | キーワード — 案件名および説明のLICC一致(項目間はOR)。 |
| minValue | number | null | 最小推定価格(CZK)。価格のない入札も通過します。 |
| maxValue | number | null | 最大推定価格(CZK)。価格のない入札も通過します。 |
| emailDigest | boolean | 日次メールダイジェスト(デフォルト:true) |
| active | boolean | 有効なフィルター(デフォルト:true) |
Webhookはフィルターに設定されなくなりました — セクションを参照してください Webhook 以下(アカウントレベルのエンドポイント)。フィールド webhookUrl はセキュリティ上の理由によりHTTP 410で拒否されます。
例
プラハの建設案件(50万CZK超)
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "プラハ建設 500k+",
"regions": ["CZ010"],
"industryTags": ["con_buildings", "con_trades"],
"minValue": 500000
}' \
https://veritra.io/api/v2/leads/filtersIT開発およびSWライセンス(全地域)
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "IT開発 + SWライセンス",
"industryTags": ["it_development", "it_licensing", "it_data_ai"],
"keywords": ["informační systém"、"modul"]
}' \
https://veritra.io/api/v2/leads/filters公共照明(CZ)— タグ+キーワードの組み合わせ
curl -X POST -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "公共照明(CZ)",
"industryTags": ["goods_electrical", "con_civil"],
"keywords": ["osvětlení"、"VO "、"veřejné osvětlení"、"lampy"],
"minValue": 200000
}' \
https://veritra.io/api/v2/leads/filtersフィルターを無効化する
curl -X PATCH -H "X-Api-Key: mrw_live_…" \
-H "Content-Type: application/json" \
-d '{"active": false}' \
https://veritra.io/api/v2/leads/filters/<id>配信方式 — Webhook vs ポーリング
新規案件を自社ERPに取り込む方法は2種類あります。多くのインテグレーターは両方を組み合わせて使用します。
Webhook(プッシュ)
Veritra はマッチ発生から約2秒以内に、案件の完全なペイロードを含む leads.match.created イベントを指定エンドポイントへ POST します。
メリット: リアルタイム、ポーリングオーバーヘッドなし、サーバーサイドゲーティング。
デメリット: 公開HTTPSエンドポイントが必要、HMAC検証、冪等性ハンドリングが必要。
ポーリング(プル)
自社ERPが定期的に(例: 5分ごと)GET /api/v2/leads/matches?since=… を呼び出します。指定タイムスタンプ以降のマッチを返します。
メリット: 公開エンドポイント不要、実装が簡単、再起動に対して安全。
デメリット: 5〜10分の遅延、レート制限あり(管理APIは60リクエスト/分)、無駄な空レスポンスが発生する。
マッチの取得
/api/v2/leads/matchesクエリパラメータ
| パラメータ | 種別 | 説明 |
|---|---|---|
| filterId | string | 特定のフィルターで絞り込む |
| qText | string | 検索テキスト(title + description の全文検索)。 |
| since | string (ISO 8601 datetime) | 指定日時以降のマッチのみ(ISO datetime形式) |
| delivered | boolean | false = 未配信のみ、true = 配信済みのみ |
| view | "starred" | "excluded" | 特殊ビュー: starred(お気に入り)| excluded(非表示)。 |
| sort | "newest" | "deadline" | "value" | 並び順: newest(デフォルト)、deadline(昇順)、value(降順)。 |
| limit | number | 取得件数(最大1,000件、デフォルト:50件)。1,000件超の場合はnextCursorページネーションまたは/matches/exportをご利用ください。 |
| cursor | string | 前ページのキーセットカーソル(pagination.nextCursor)。 |
返却されたマッチは自動的にdelivered=trueとしてマークされます。リクエストごとに1クレジットを消費します。
matchId のフォーマット
matchId は取得元に応じて2種類のフォーマットがあります:
cm…(cuid プレフィックス)— 事前計算済み LeadMatch テーブル(毎日マッチ済み案件をペアリングするcronジョブ)から返されます。呼び出し間で安定しており、mark-as-viewed に使用可能です。live-12345synthetic プレフィックスは、search / browse モード(qText パラメータ、view=starred/excluded)経由でライブ検出されたマッチに付与されます。LeadMatch テーブルには存在しないため、mark-as-viewed は無操作(no-op)となります。tenderId はハイフン以降のサフィックスです。
例
curl -H "X-Api-Key: mrw_leads_…" \ "https://veritra.io/api/v2/leads/matches?delivered=false&limit=10"
レスポンス
{
"data": [
{
"matchId": "cm…",
"filterId": "cm…",
"filterName": "プラハ建設案件",
"matchedAt": "2026-04-03T06:00:00.000Z",
"viewedAt": null,
"delivered": true,
"tender": {
"id": 12345,
"title": "橋梁No.123の改修",
"estimatedValue": 12500000,
"deadlineAt": "2026-05-15T22:00:00.000Z",
"publishedAt": "2026-04-01T08:00:00.000Z",
"firstSeenAt": "2026-04-01T08:30:00.000Z",
"url": "https://nen.nipez.cz/...",
"portalType": "NEN",
"cpvCode": "45000000",
"tenderType": "OFFERS",
"contractingAuthority": {
"ico": "12345678",
"name": "Město Praha",
"region": "Praha",
"district": "Praha 1"
},
"documents": [
{ "name": "Výzva.pdf", "url": "https://nen.nipez.cz/…", "fileType": "pdf", "fileSizeBytes": 320000 }
],
"starred": false,
"excluded": false
}
}
],
"pagination": { "nextCursor": "eyJmaXJzdFNlZW5BdC…", "totalCount": 42 }
}次のページを取得するには、pagination.nextCursor を ?cursor= パラメータとして送信してください。
マッチに対するアクション
スター(お気に入り登録)、除外(非表示)、閲覧(既読マーク)はテンダー単位の設定であり、UserTenderPreference に保存されます。
/api/v2/leads/matches/:matchIdレスポンス:matches リストアイテムと同一の構造。
/api/v2/leads/matches/:matchId/star{ "starred": true }/api/v2/leads/matches/:matchId/exclude{ "excluded": true }/api/v2/leads/matches/:matchId/viewsynthetic live-:id マッチの場合はno-op(マークすべき行が存在しません)。
/api/v2/leads/preferences{
"data": {
"starred": [12345, 67890],
"excluded": [54321]
}
}タクソノミー
フィルター値用の静的リファレンスカタログ。ロケール対応ラベル付き。
/api/v2/leads/taxonomy/industry?locale=cs{
"data": {
"locale": "cs",
"areas": [{ "id": "construction", "icon": "🏗️", "label": "Stavebnictví" }, …],
"tags": [
{ "id": "con_buildings", "area": "construction", "label": "Pozemní stavby", "cpvPrefixes": ["452"] },
…
]
}
}/api/v2/leads/taxonomy/cpv?locale=csレスポンス: ツリー構造 セクション → グループ → クラス → カテゴリ → サブカテゴリ。
Webhook
Webhookエンドポイント(CRUD、シークレットローテーション)はアカウントレベルの機能です — Account API → Webhook にて一括して説明しています。ここではリード固有のイベントペイロード(leads.match.created)とHMAC検証についてのみ説明します。
イベントの配信
新しいマッチが発生した際、イベントタイプ leads.match.created をヘッダー内のHMAC-SHA256署名とともに送信します。ヘッダー X-Signature-256 にはidempotencyキー、X-Idempotency-Key にはタイプを含めます。X-Event-Type。障害時は最大約33時間、指数バックオフによるリトライを行います。
リトライポリシー
エンドポイントが non-2xx を返した場合(または10秒以内に応答しない場合)、Veritra は指数バックオフでリトライします:1分、5分、30分、2時間、12時間、24時間。6回失敗するとWebhookは failed としてマークされ、ダッシュボードに警告が表示されます。冪等性キーは各試行で同一のため、エンドポイントは重複排除を必ず実装してください(未実装の場合、同一マッチが最大6回処理されます)。
APIを介したエンドポイント管理
Webhookエンドポイントをダッシュボードにアクセスせずに管理できます。アカウントあたり最大5エンドポイントまで。
/api/v2/account/webhooks/api/v2/account/webhooks/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/api/v2/account/webhooks/:id/rotate-secret/api/v2/account/webhooks/:id/test/api/v2/account/webhooks/:id/deliveries/api/v2/account/webhooks/:id/deliveries/:deliveryId/replayHMAC署名検証
サーバーは HMAC-SHA256(secret, raw_body) でペイロードに署名し、<code>sha256=hex</code> 形式で <code>X-Signature-256</code> ヘッダーに付与して送信します。タイミング攻撃への脆弱性を防ぐため、定数時間比較(constant-time comparison)で検証してください。
// Node.js (Express)
import crypto from "node:crypto";
const WEBHOOK_SECRET = process.env.MRICKWOOD_WEBHOOK_SECRET!;
function verify(rawBody: string, sig: string | undefined): boolean {
if (!sig) return false;
const expected = "sha256=" + crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
// Constant-time comparison (timing-safe)
const a = Buffer.from(sig);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post("/webhooks/veritra",
express.raw({ type: "application/json" }),
async (req, res) => {
const raw = req.body.toString("utf8");
if (!verify(raw, req.header("X-Signature-256"))) {
return res.status(401).send("Invalid signature");
}
const idempKey = req.header("X-Idempotency-Key")!;
const evt = JSON.parse(raw);
// Idempotency: store idempKey, skip if already processed
if (await alreadyProcessed(idempKey)) return res.status(200).send("ok");
await processEvent(evt);
await markProcessed(idempKey);
res.status(200).send("ok"); // Must be 2xx within 10s
},
);# Python (Flask)
import hmac, hashlib, os
from flask import Flask, request, abort
WEBHOOK_SECRET = os.environ["MRICKWOOD_WEBHOOK_SECRET"]
def verify(raw: bytes, sig: str | None) -> bool:
if not sig: return False
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), raw, hashlib.sha256
).hexdigest()
return hmac.compare_digest(sig, expected)
@app.post("/webhooks/mrickwood")
def webhook():
raw = request.get_data()
if not verify(raw, request.headers.get("X-Signature-256")):
abort(401)
# ... idempotency check + process
return "ok", 200{
"id": "evt_…",
"type": "leads.match.created",
"createdAt": "2026-04-03T06:00:00.000Z",
"data": {
"filterId": "cm…",
"filterName": "プラハ建設案件",
"matchId": "cm…",
"tender": { "id": "12345", "title": "…", "estimatedValue": 12500000 }
}
}メールダイジェスト
S emailDigest: trueを設定すると、新着案件の概要を記載したメールが毎日届きます。ダイジェストは毎朝(UTC 5:00)アカウントに登録されたメールアドレスへ送信されます。フィルターを編集することで無効化できます。
制限
| パラメータ | 種別 | 説明 |
|---|---|---|
| トライアル | 500 リクエスト/月 | 1日間無料。カード/請求プロファイル不要。デフォルト ApiKey.requestsLimit。 |
| 有料プラン | 無制限 | 月次制限は無効です。技術的なレート制限(100回/時間/キー)のみ適用されます。 |
| フィルター | 20 | アカウントあたりのアクティブフィルターの最大数。 |
| Webhookエンドポイント | 5 | アカウントあたりのアクティブWebhook URLの最大数。 |
月次制限を超過すると、APIは Retry-After ヘッダー付きで 429 を返します。制限は毎月1日にリセットされます。