Japan Public Tender Alerts — kkj.go.jp Bid Monitoring avatar

Japan Public Tender Alerts — kkj.go.jp Bid Monitoring

Pricing

from $3.00 / 1,000 new tender records

Go to Apify Store
Japan Public Tender Alerts — kkj.go.jp Bid Monitoring

Japan Public Tender Alerts — kkj.go.jp Bid Monitoring

New Japanese government tender notices (入札公告) from kkj.go.jp, filtered by keyword, prefecture and date. Returns only records new since the last run, as clean JSON. Official public API, no login or key. 官公需情報ポータルの入札公告を絞り込み、前回実行からの新着だけを構造化データで返します。

Pricing

from $3.00 / 1,000 new tender records

Rating

0.0

(0)

Developer

Hullspark

Hullspark

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Categories

Share

Get new Japanese government tender notices (入札公告) in Slack, Discord, Teams or a spreadsheet — without checking kkj.go.jp every morning. Pick keywords and prefectures once, schedule the Actor, and each run returns only the tenders you have not seen before, as clean JSON/CSV. Source: the official kkj.go.jp search API (public, no login, no API key).

毎朝 kkj.go.jp を見に行かなくても、キーワードと都道府県を一度決めれば、前回から増えた入札公告だけが Slack / Discord / Teams / スプレッドシートに届きます(公式の公開 API を使用。ログイン・キー不要)。

Independent tool, not affiliated with kkj.go.jp, the Small and Medium Enterprise Agency or any government body. 本 Actor は非公式のツールです。

Who is this for?

  • Small and mid-size contractors and suppliers that want to hear about public-sector work (cleaning, construction, IT, goods) without opening kkj.go.jp every morning.
  • Bid consultants and sales teams that watch several keywords and prefectures for a client and want one clean feed.
  • Analysts who need a date range of notices as a spreadsheet to see which bodies buy what.
Slack message produced by the Actor: new tender notices for the keyword 清掃 in Tokyo, with title, issuing body, category and announcement date

What you get

  • Only what is new. Tenders already delivered in an earlier run are skipped (and not billed). The "already seen" list lives in a named key-value store in your Apify account — see How "new since last run" works.
  • A message people can read. Set webhookUrl + webhookFormat (slack, discord, teams) and each run posts the title, issuing body, opening date and link. Default json keeps the raw data for automations (Zapier, Make, n8n).
  • Structured data. Title, issuing organization, prefecture/city, category (物品/工事/役務), procedure type, announcement and opening dates, attachments, source link, as JSON, CSV or Excel.
  • Nationwide in one run. Leave prefectures empty and the Actor queries each prefecture and merges the results, so large result sets are not silently cut off.
  • Contact details removed by default. Phone numbers, e-mail addresses and staff names in the announcement text are masked by pattern matching (best effort — it can miss unusual formats).

30-second quick start

  1. Click Try for free — the form is pre-filled with keyword 清掃 (cleaning), prefecture 東京都, 10 items. Press Start.
  2. Open the Output tab: a table of tenders announced in the last 7 days.
  3. Happy with the result? Click Schedule (daily or weekly) and, optionally, paste a Slack/Discord/Teams webhook URL. Run it again later: only new tenders appear.

The first run on a new keyword set returns everything from the last 7 days (up to maxItems); from the second run on, only tenders you have not received before.

Example input:

{
"keywords": ["清掃"],
"prefectures": ["東京都"],
"publishedAfter": "2026-10-06",
"maxItems": 10,
"webhookUrl": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
"webhookFormat": "slack"
}

Use cases

  • Daily/weekly bid-opportunity feed — Schedule the Actor with your industry keywords and target prefectures. With onlyNew: true (default) you're only charged for announcements you haven't seen before, and webhookUrl can forward them straight into Slack/Discord/your CRM via Apify's integrations.
  • Lead generation for contractors and suppliers — Track a specific category (物品/工事/役務) nationwide or in the prefectures you operate in, to spot upcoming public-sector work without paying for a commercial tender-alert subscription.
  • Market research — Pull a date range and category/prefecture combination into a dataset to see which government bodies are buying what, as a one-off export (JSON/CSV/Excel) rather than a recurring subscription.

スケジュール実行でキーワード・都道府県を設定し、onlyNew: true(既定)で新着分だけ課金・webhookUrlでSlack/Discord/CRMへ転送する「入札アラート」、特定のcategory(物品/工事/役務)を追う「営業リード探索」、期間・都道府県を指定してデータセットとしてJSON/CSV/Excelで書き出す「市場調査」などに使えます。

Example output (one dataset item; real record from a run on 2026-10-13, description shortened):

{
"id": "kkj:dG9reW8vdG9zaGltYV9jaXR5LzIwMjYvMjAyNjEwMDlfMDAwMDcK",
"title": "豊島区人事関連事務業務委託プロポーザルを実施します",
"organization": "東京都豊島区",
"prefecture": "東京都",
"city": "豊島区",
"category": "役務",
"announcedAt": "2026-10-09T00:00:00+09:00",
"description": "豊島区人事関連事務業務委託プロポーザルを実施します …",
"descriptionTruncated": false,
"attachments": [{ "name": "豊島区人事関連事務業務委託 仕様書(PDF:501KB)", "url": "https://www.city.toshima.lg.jp/documents/58037/20261008142736.pdf" }],
"sourceUrl": "https://www.city.toshima.lg.jp/documents/58037/20261008142620.pdf",
"isNew": true,
"fetchedAt": "2026-10-13T05:49:36.341Z"
}

How keywords are matched. Your keywords are sent to kkj.go.jp's own full-text search as one query joined with OR. kkj matches the notice title and body text (and, according to kkj, attached documents). A hit therefore does not always have the word in its title. In a check on 2026-10-13 with 清掃 in Tokyo, 4 of 15 notices had it in the title and 10 only in the body. The Actor does no extra filtering of its own; the organization name is not searched by keywords.

What a Slack message looks like (webhookFormat: "slack"):

入札公告 新着 1 件(清掃)
• 豊島区人事関連事務業務委託プロポーザルを実施します
東京都豊島区 / 東京都 役務 公告 2026-10-09

Input examples

Daily alert for construction work in the Kanto region (one category per run; run it once per category if you need several):

{
"keywords": ["改修", "外壁"],
"prefectures": ["東京都", "神奈川県", "埼玉県", "千葉県"],
"category": "工事",
"maxItems": 50,
"webhookUrl": "https://discord.com/api/webhooks/XXX/YYY",
"webhookFormat": "discord"
}

Nationwide goods tenders as a one-off spreadsheet (everything in a date range, not only new items):

{
"keywords": ["パソコン"],
"category": "物品",
"publishedAfter": "2026-09-01",
"onlyNew": false,
"maxItems": 200
}

Plain data for Zapier, Make or n8n (keep the default raw payload):

{
"keywords": ["システム開発"],
"prefectures": ["大阪府"],
"webhookUrl": "https://hooks.zapier.com/hooks/catch/XXX/YYY/",
"webhookFormat": "json"
}

Integrations

  • Slack / Discord / Microsoft Teams: paste the incoming-webhook URL into webhookUrl and choose the matching webhookFormat. (The Teams payload is an Adaptive Card message for Workflows / incoming webhooks; Discord posts are limited to 2,000 characters and list as many tenders as fit.)
  • Anything else: keep webhookFormat: "json" for the raw payload { "newTenders": [...], "totalNewCount": n, "truncatedForWebhook": false }, or use Apify's own integrations (Zapier, Make, n8n, Google Sheets) on the dataset.
  • Schedule: Apify Schedules (cron) in the Console. API: run and read the dataset over the Apify API/clients.

Input

FieldTypeDefaultDescription
keywordsstring[][]Full-text search terms (OR), matched by kkj.go.jp against title and body text (see above). Empty = no keyword filter.
prefecturesstring[][]Prefecture names (e.g. 東京都). Empty = nationwide (fetched per prefecture and merged).
categorystring""物品 (goods) / 工事 (construction) / 役務 (services). The kkj API accepts one category per run — run the Actor once per category if you need several.
publishedAfterstring (YYYY-MM-DD)7 days before the runOnly tenders announced on/after this date.
onlyNewbooleantrue"Only tenders not delivered before": output (and bill) only tenders not delivered in an earlier run. false = everything, flagged with isNew.
includeContactbooleanfalseKeep the announcement text unmasked.
maxItemsinteger20Max items per run (also caps the new-item charge). One prefecture returns at most 200 records per run (memory safety); several prefectures/nationwide are collected per prefecture and then cut to maxItems.
webhookUrlstring—POST new tenders here after the run (only when there is at least one new tender).
webhookFormatjson | slack | discord | teamsjsonBody format for webhookUrl.
stateStoreNamestringautomaticAdvanced: name of the key-value store holding the "already seen" list.

How "new since last run" works

On the Apify platform every run gets its own fresh default storage, so remembering earlier runs needs a named key-value store. This Actor keeps the list of tender IDs it has already delivered (for 90 days) in a store called kkj-seen-<hash> in the account that runs it, where <hash> is derived from your keywords, prefectures and category. Consequences:

  • Scheduled runs with the same keywords/prefectures/category share one list; a different keyword set starts its own list, so two alerts do not hide each other's results.
  • Changing only publishedAfter, maxItems or the webhook keeps the list.
  • To start over, delete that store under Storage → Key-value stores in the Console. To share or separate lists on purpose, set stateStoreName.
  • A tender is recorded as seen only when it was actually written to the dataset in that run. If the run's spending limit stops it early, the remaining tenders are delivered next time.

Output fields

Dataset table of new tender notices from kkj.go.jp for keyword 清掃 in Tokyo: announcement date, organization, category and title One tender notice as a dataset item: title, organization, prefecture, category, announcement date, description, attachments, source link
FieldDescription
idStable ID (kkj: + kkj record key)
titleProject name (件名)
organization, prefecture, cityIssuing body and its location
category物品 / 工事 / 役務
procedureTypee.g. 一般競争入札. kkj sends it for only some notices (in 2026-10-13 samples: 1 of 15, 0 of 30, 29 to 68 of 100), so the field is left out when kkj does not give it. It is never the text undefined.
announcedAt, tenderSubmissionStartAt, openingAt, deliveryDeadlineAtDates, when published
location, itemCode, certificationWhen published
description, descriptionTruncatedAnnouncement text as provided by kkj (masked unless includeContact; capped at 50,000 characters)
attachmentsLinked documents
sourceUrlLink to the original page. For some issuing systems this is a generic portal entry page rather than a deep link.
isNewFirst time this alert delivered the tender

A run also writes a summary to the key-value store key OUTPUT: totalFetched, totalSearchHits, searchTruncated, skippedLgCodes, newCount, pushedCount, stateStore, and a suggested nextRecommendedPublishedAfter.

Field names are English; values (titles, organization names) stay in Japanese — no translation is done.

Pricing

Pay-per-event: $0.05 per run (actor-start) + $0.003 per tender written to the dataset (tender-record; with onlyNew: true that means new tenders only).

What that means in practice:

What you doCost
First trial with the pre-filled form (10 tenders)at most $0.08 ($0.05 + 10 × $0.003)
Weekly alert, about 50 new tenders per runabout $0.80 a month (4 × $0.05 + 200 × $0.003)
Daily alert, about 5 new tenders a dayabout $1.95 a month (30 × $0.05 + 150 × $0.003)
A day with nothing new$0.05 (start fee only; nothing is sent to your webhook)

maxItems (default 20) also caps the charge for one run, and Maximum cost per run in the Console is a hard ceiling.

Other Store Actors read the same kkj.go.jp data. Some add English field names and contract award results, some add AI extraction of deadlines and qualification requirements (priced per enriched record), and one watches the central-government portal (p-portal.go.jp) instead. This Actor is deliberately smaller: new-only delivery across runs, nationwide merging, and ready-made Slack/Discord/Teams messages at a low per-tender price. It does not include award results or AI extraction.

Free alternative worth knowing about: kkj.go.jp can deliver saved searches as an RSS feed (kkj.go.jp). If an RSS reader is enough for you, use it. This Actor adds: nationwide merging per prefecture, a de-duplicated "new only" list across runs, structured fields, and delivery to Slack/Discord/Teams/Sheets/API.

Limits (please read)

  • Freshness: kkj lists a notice about a day after it is published; the Actor adds no delay of its own.
  • Coverage and accuracy depend on kkj.go.jp. The Actor does not guarantee completeness or timeliness.
  • Announcements only: award results (who won, at what price) are not included.
  • One category per run; 200 records per prefecture per run. If searchTruncated is true in OUTPUT, narrow publishedAfter or add keywords.
  • Descriptions are what kkj extracted from the original notice; for notices published as PDF they can contain stray metadata or garbled characters.
  • Very large records: a few records on kkj are extremely large. To protect memory, a prefecture whose response exceeds a safety limit is skipped for that run and listed in skippedLgCodes.
  • sourceUrl may point to a portal that requires login for bidding; the Actor itself never logs in.
  • The first run on the platform after this update starts with an empty "already seen" list, so it can report tenders you already received earlier.

FAQ

Does it send e-mail? Not by itself. Use a Slack, Discord or Teams webhook, or Apify's own integrations (e-mail, Google Sheets, Zapier, Make, n8n) on the dataset.

Why does a result not contain my keyword in the title? kkj matches the keyword against the notice title and body (and attachments, according to kkj). See "How keywords are matched" above.

Can I get several categories in one alert? The kkj API takes one category per run. Create one saved task per category (each keeps its own "already seen" list).

Are award results (who won, at what price) included? No, announcements only.

Will I get the same tender twice? Not with onlyNew: true (default) and the same keywords, prefectures and category. The first run after the Actor was updated on the platform started with an empty list, so it could repeat earlier tenders once.

How do I reset an alert? Delete its kkj-seen-<hash> key-value store under Storage → Key-value stores.

Is my webhook URL private? It is part of your run input, which is visible in your Apify account. Use a webhook that only posts into a channel you control, and rotate it if it leaks.

What does a day with nothing new cost? The start fee only ($0.05), and no webhook message is sent.

Changelog

  • 0.2.1 — Hardening: procedureType (and any other field kkj does not send) is now always left out of the item when kkj does not send it, never carried as an undefined value. Added a note on which fields keyword matching uses. The "Only new" input is now labelled "Only tenders not delivered before (new only)".

Disclaimer and support

Only publicly published notices are read, through kkj.go.jp's official public API; no login, scraping or circumvention is involved. Found a bug or need a field added? Open an issue on the Actor's Issues tab.