新着

入札監視

地域、業種タグ、キーワード、金額範囲などのフィルターに基づき、新規案件を自動配信 — 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/メールダイジェストをご利用ください — 後述を参照。

推奨事項: フィルタリングには、categories(CPV)よりも常に industryTags を優先してください。当社の industryTags は、LLMによる入札分類とCPVマッピングを統合したものであり、CPVの誤記に対して堅牢です。チェコ共和国の発注者は、過度に汎用的または無関係なCPVコードを割り当てることが多く(例:具体的なプレフィックスの代わりに汎用的な「45000000-0」を建設案件に使用)、CPVフィルターのみでは関連案件の一部が見落とされる可能性があります。

案件検索(アドホック)

すべてのアクティブな入札案件を横断的に一度だけ検索する場合に使用します。保存済みフィルターは使用せず、パラメーターはクエリ文字列で直接指定します。

GET/api/v2/leads/tenders/search

クエリパラメーター

パラメータ種別説明
qText*string検索テキスト(title + description の全文検索)。
regionsstringNUTSリーフコード CSV形式(CZ010,CZ020)。
cpvPrefixesstringCPVプレフィックス CSV形式(45,452)。
industryTagsstring業種タグID CSV形式(con_buildings,it_development)。
minValuenumber最小推定価格(CZK)。価格のない入札も通過します。
maxValuenumber最大推定価格(CZK)。価格のない入札も通過します。
deadlineFromstring (YYYY-MM-DD)提出期限 >= YYYY-MM-DD。
deadlineTostring (YYYY-MM-DD)提出期限 <= YYYY-MM-DD。
sort"newest" | "deadline" | "value"並び順: newest(デフォルト)、deadline(昇順)、value(降順)。
limitnumber取得件数(最大1,000件、デフォルト:50件)。1,000件超の場合はnextCursorページネーションまたは/matches/exportをご利用ください。
cursorstring前ページのキーセットカーソル(pagination.nextCursor)。

curl -H "X-Api-Key: mrw_live_…" \
  "https://veritra.io/api/v2/leads/tenders/search?qText=rekonstrukce&regions=CZ010,CZ020&minValue=500000&limit=10"
GET/api/v2/leads/tenders/:id

レスポンス:id、title、description、estimatedValue、deadlineAt、contractingAuthority、documents[]、starred、excluded フィールドを持つ data オブジェクト。

POST/api/v2/leads/tenders/:id/email

リクエストボディに recipientEmail を含めることで、別のメールアドレスへ転送できます。デフォルトは user.email です。

GET/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時間キャッシュ。公開エンドポイントのため認証不要。

GET/api/v2/leads/zadavatele?q=praha
GET/api/v2/leads/countries
GET/api/v2/leads/regions?country=CZ
GET/api/v2/leads/regions/catalog?country=CZ&locale=cs
GET/api/v2/leads/taxonomy/industry
GET/api/v2/leads/taxonomy/cpv
Search と Filter の違い: Searchは単発クエリで、案件の現在のスナップショットを返します。Filter(後述)は保存された条件であり、新規案件をWebhookまたはメールダイジェストで継続的に通知します。

フィルタリング可能な項目と許容値

フィルターは以下のフィールドで構成されます。`name` を除きすべて任意項目です。空フィールド = 当該ディメンションに制限なし。

regions string[]

指定国のNUTSリージョン(?country=CZ)。ロケールごとのラベル付き。

フィルターはEU全域対応です: `regions` の値は、以下に示すEU加盟国のいずれかのNUTSコードです。フィルターは、有効なLEADSサブスクリプション(サブスクリプションスコープ)が適用されているリージョンのみを返します。CZ + SKのみ契約している場合、DEのNUTSコードはフィルターによって無視されます。
対応国(NUTS-0)
CZČeská republika
SKSlovensko
PLPolsko
DENěmecko
ATRakousko
FRFrancie
ESŠpanělsko
ITItálie
NLNizozemsko
BEBelgie
PTPortugalsko
SEŠvédsko
FIFinsko
DKDánsko
NONorsko
IEIrsko
GRŘecko
RORumunsko
BGBulharsko
HUMaďarsko
HRChorvatsko
SISlovinsko
LTLitva
LVLotyšsko
EEEstonsko
LULucembursko
CYKypr
MTMalta
CHŠvýcarsko
ISIsland
MKSeverní Makedonie
GBVelká Británie
JPJaponsko

特定国の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 Praha
CZ020Středočeský kraj
CZ031Jihočeský kraj
CZ032Plzeňský kraj
CZ041Karlovarský kraj
CZ042Ústecký kraj
CZ051Liberecký kraj
CZ052Královéhradecký kraj
CZ053Pardubický kraj
CZ063Kraj Vysočina
CZ064Jihomoravský kraj
CZ071Olomoucký kraj
CZ072Zlínský kraj
CZ080Moravskoslezský kraj

industryTags string[] 推奨

マルチタグによる業種分類。案件には複数のタグを付与できます(例:改修工事の場合「stav_pozemni」+「stav_remesla」)。指定したタグのうち少なくとも1つに一致する案件をフィルタリングします(JSON_OVERLAPS)。

CPVよりindustryTagsを優先すべき理由: 当社のindustryTagsは、案件名・説明のLLM分類、CPVマッピング、正規表現ヒントを組み合わせて生成されます。CPVコードの割り当てが不正確な発注者の案件も適切に捕捉できます。CPVフィルターは精度が高い反面、発注者の規律に依存しており、チェコ共和国ではその水準が低い傾向にあります。

13分野・48タグ
🏗️Stavebnictví
con_buildingsPozemní stavby a rekonstrukce budov
con_civilInženýrské stavby (silnice, mosty, voda)
con_tradesStavební řemesla a dílčí práce
con_energy_efficiencyEnergetické úspory a OZE
con_materialsStavební materiál
📐Projektování a dozor
des_documentationProjektová dokumentace a studie
des_supervision_ohsTechnický dozor a BOZP
des_surveyingGeodézie a pozemkové úpravy
💻IT a software
it_developmentVývoj SW a integrace
it_licensingSW licence a předplatné
it_hardwareHW a infrastruktura
it_cybersecurityKybernetická bezpečnost
it_data_aiData, analytika, AI/ML
📡Telekomunikace
telecom_internetTelekomunikace, internet, mobilní
🧑‍💼Profesionální služby
prof_marketingMarketing, PR, reklama
prof_legalPrávní služby
prof_accountingÚčetnictví, dotace, audit
prof_hrHR, nábor
prof_translationPřeklady a tlumočení
prof_insurancePojištění a finanční
🛡️Provoz a údržba
ops_cleaningÚklidové služby
ops_securityOstraha a recepční
ops_maintenanceÚdržba a servis zařízení
ops_wasteOdpadové hospodářství
ops_facilitySpráva nemovitostí
🍽️Stravování a ubytování
cat_cateringStravování, catering
cat_accommodationUbytování a konference
cat_foodPotraviny a nápoje
🚚Doprava a vozidla
trans_transportPřeprava cestujících a nákladu
trans_vehiclesVozidla, díly, leasing
🏥Zdravotnictví
health_pharmaLéčiva a farma
health_devicesZdravotnické přístroje a materiál
health_careZdravotní a sociální péče
📦Zboží a vybavení
goods_furnitureNábytek a vybavení interiérů
goods_clothingOděvy, OOPP, uniformy
goods_electricalElektromateriál
goods_machineryPrůmyslové stroje
Energetika a vodárenství
energy_fuelsPohonné hmoty a paliva
energy_power_heatElektřina a teplo
energy_waterVodárenství
🌳Příroda, lesy, bezpečnost
nat_forestryLesní hospodářství
nat_greeneryÚdržba zeleně a zahradnictví
nat_agricultureZemědělství
defense_safetyHasiči, vojsko, obrana
🔬Věda a vzdělávání
sci_labLaboratorní a měřicí vybavení
sci_researchVýzkum a vývoj
edu_trainingVzdělávání a školení
culture_mediaKultura, knihy, média
タグが見つかりませんか? お探しの業種タグが見つからない場合は、こちらまでご連絡ください: michal@veritra.io — 追加いたします。

categories string[] 精度低

任意の長さのCPV(共通調達語彙)プレフィックス — `LIKE 'prefix%'` によるマッチング。例:「45」ですべての建設部門、「4523」で土木工事のみ、「45316110」で街路照明のみに一致します。

最頻出CPV部門(2桁)上位35件
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のみ、または両方を指定できます。

重要: 推定価格が未入力(estimatedValueがnullまたは0)の案件は、両方向のフィルターを通過します。多くの発注者が価格を入力しないため、除外するとそれらの案件を見逃すことになります。

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クレジットを消費しないため、フィルターの管理は毎日の案件取得に影響しません。

GET/api/v2/leads/filters
POST/api/v2/leads/filters
GET/api/v2/leads/filters/:id
PATCH/api/v2/leads/filters/:id
DELETE/api/v2/leads/filters/:id
GET/api/v2/leads/filters/:id/matches/export?format=csv|xlsx|json&view=all|starred|excluded

ボディパラメータ(POST / PUT)— 共通

パラメータ種別説明
name*stringフィルター名(最大120文字)
regionsstring[]NUTSコード(例:`CZ010`)。任意のレベルを混在可。空の配列 = 全地域。
industryTagsstring[]推奨パス。当社タクソノミーのタグID(例:'stav_pozemni'、'it_vyvoj')。マルチタグ — 項目間はOR。
categoriesstring[]任意の長さのCPVプレフィックス(例:'45'、'4523'、'45316110')。industryTagsより精度は低め。
keywordsstring[]キーワード — 案件名および説明のLICC一致(項目間はOR)。
minValuenumber | null最小推定価格(CZK)。価格のない入札も通過します。
maxValuenumber | null最大推定価格(CZK)。価格のない入札も通過します。
emailDigestboolean日次メールダイジェスト(デフォルト:true)
activeboolean有効なフィルター(デフォルト:true)

Webhookはフィルターに設定されなくなりました — セクションを参照してください Webhook 以下(アカウントレベルのエンドポイント)。フィールド webhookUrl はセキュリティ上の理由によりHTTP 410で拒否されます。

キーワードは、発注者が公開する言語(現時点では常にチェコ語)で案件名および説明を検索します(LIKE %kw%)。

プラハの建設案件(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/filters

IT開発および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リクエスト/分)、無駄な空レスポンスが発生する。

推奨構成: 主にWebhookを使用し、Webhookのリトライバジェットを超えた配信失敗への安全網として、日次ポーリング(since=yesterday)を併用する。

マッチの取得

GET/api/v2/leads/matches

クエリパラメータ

パラメータ種別説明
filterIdstring特定のフィルターで絞り込む
qTextstring検索テキスト(title + description の全文検索)。
sincestring (ISO 8601 datetime)指定日時以降のマッチのみ(ISO datetime形式)
deliveredbooleanfalse = 未配信のみ、true = 配信済みのみ
view"starred" | "excluded"特殊ビュー: starred(お気に入り)| excluded(非表示)。
sort"newest" | "deadline" | "value"並び順: newest(デフォルト)、deadline(昇順)、value(降順)。
limitnumber取得件数(最大1,000件、デフォルト:50件)。1,000件超の場合はnextCursorページネーションまたは/matches/exportをご利用ください。
cursorstring前ページのキーセットカーソル(pagination.nextCursor)。

返却されたマッチは自動的にdelivered=trueとしてマークされます。リクエストごとに1クレジットを消費します。

matchId のフォーマット

matchId は取得元に応じて2種類のフォーマットがあります:

  • cm… (cuid プレフィックス)— 事前計算済み LeadMatch テーブル(毎日マッチ済み案件をペアリングするcronジョブ)から返されます。呼び出し間で安定しており、mark-as-viewed に使用可能です。
  • live-12345 synthetic プレフィックスは、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 に保存されます。

GET/api/v2/leads/matches/:matchId

レスポンス:matches リストアイテムと同一の構造。

POST/api/v2/leads/matches/:matchId/star
{ "starred": true }
POST/api/v2/leads/matches/:matchId/exclude
{ "excluded": true }
POST/api/v2/leads/matches/:matchId/view

synthetic live-:id マッチの場合はno-op(マークすべき行が存在しません)。

GET/api/v2/leads/preferences
{
  "data": {
    "starred": [12345, 67890],
    "excluded": [54321]
  }
}

タクソノミー

フィルター値用の静的リファレンスカタログ。ロケール対応ラベル付き。

GET/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"] },
      …
    ]
  }
}
GET/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エンドポイントまで。

GET/api/v2/account/webhooks
POST/api/v2/account/webhooks
Webhookシークレットは一度しか表示されません! POST /webhooks のレスポンスにフィールド 'secret' が含まれます — すぐに環境変数(例:VERITRA_WEBHOOK_SECRET)に保存してください。後から取得することはできません。紛失した場合は /rotate-secret を使用して新しいシークレットを生成してください(旧シークレットは即時無効化されます)。
GET/api/v2/account/webhooks/:id
PATCH/api/v2/account/webhooks/:id
DELETE/api/v2/account/webhooks/:id
POST/api/v2/account/webhooks/:id/rotate-secret
POST/api/v2/account/webhooks/:id/test
GET/api/v2/account/webhooks/:id/deliveries
POST/api/v2/account/webhooks/:id/deliveries/:deliveryId/replay

HMAC署名検証

サーバーは 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日にリセットされます。