コンテンツにスキップ

API Reference

要約 (summary): REST API の全エンドポイント仕様。programs / exclusions / meta / billing の各メソッドについて params, response, 認証要否, rate limit を記載。

ベース URL

https://api.autonomath.ai

バージョニングポリシー (Versioning policy)

エンドポイントは 2 種類に分かれる。契約の強さが異なるので、統合時に意識する。

/v1/* — 安定契約 (stable contract): - /v1/programs/*, /v1/exclusions, /v1/billing/* など、/v1/ prefix を持つ全エンドポイント - response schema の破壊的変更はしない - マイナー改訂は 追加のみ (additive): 新しい任意フィールド、新しい optional query parameter、新しいエンドポイントの追加 - 破壊的変更が必要になった場合は /v2/* を新設し、/v1/* は最低 6 ヶ月並走させてから deprecate - deprecation は response の Sunset / Deprecation header と docs 更新で 90 日以上前に告知

/healthz, /meta, /v1 prefix を持たない utility 系 — ライフサイクル扱い (lifecycle, unversioned): - /healthz は liveness probe のみで、schema は空 object に変わる可能性あり - /meta は aggregate stats (total_programs, last_updated 等) を返すが、field 追加・削除・意味変更が発生しうる - /v1/billing/webhook は Stripe 側の event schema に追従する (Stripe 仕様に引きずられる) - これらの shape 変更は 30 日前に docs/api-reference.md と changelog で告知 するが、/v2 昇格は行わない

統合する client 側の注意: /v1/* 以外のレスポンスを business logic の入力に使わない。監視・運用系 (dashboard, health check) に限定する。

認証 (Authentication)

すべての認証付きエンドポイントは下記いずれかのヘッダーで API key を渡す:

X-API-Key: jpintel_xxxxxxxxxxxxxxxx
Authorization: Bearer jpintel_xxxxxxxxxxxxxxxx

API key を送らない場合は free tier 扱い (100 requests/day, 一部エンドポイントは利用可)。key が無効 / 取り消し済みの場合は 401 Unauthorized を返す。

匿名呼び出しの IP レート制限 (Anonymous per-IP limit)

認証ヘッダー (X-API-Key / Authorization: Bearer) を付けない呼び出しは、IP アドレス単位で 1 日 100 req / IPv4 (/32) / IPv6 (/64) に制限される。これは discoverability 系エンドポイント (/meta, /v1/ping, /v1/programs/*, /v1/exclusions/*, /v1/feedback) にのみ適用され、/healthz, /v1/billing/webhook, /v1/subscribers/unsubscribe, dashboard 系 (/v1/me/*, /v1/session) はカウントしない。

認証済み呼び出し (有効な API key 付き) はこの IP 制限を完全にバイパスし、tier ごとの quota だけが適用される。

上限超過時:

HTTP/1.1 429 Too Many Requests
Retry-After: 43200
Content-Type: application/json

{"detail": "anon rate limit exceeded", "limit": 100, "resets_at": "2026-04-24T00:00:00+09:00"}

リセットは JST midnight (sliding window ではなく暦日)。Retry-After は次の JST 00:00 までの秒数。IP は raw のまま保存されず、HMAC-SHA256(ip, api_key_salt) で hash 化される。

Rate limit (tier)

Tier Daily limit 計測
free 100 key 無し / free key 共通
paid metered (Stripe 従量) 上限なし、¥0.5/req 税別で請求

注: 価格と計測方法の最新値は pricing.md を参照。

free 上限超過時は 429 Too Many Requests, body に {"detail": "daily limit of 100 exceeded for tier=free"}。レスポンスに Retry-After: <seconds to UTC midnight> header を含む。paid は cap なし (スパイクでも 429 は返らない)。


Programs

GET /v1/programs/search

自由記述 + 構造化フィルタで制度を検索。

認証: 任意 (未認証は free tier)

Query parameters:

name type required description
q string no 自由記述検索。3 文字以上で FTS5 trigram、2 文字以下は substring 一致
tier string (repeat) no S / A / B / C / X。複数指定で OR
prefecture string no 都道府県名 (完全一致, 例: 青森県)
authority_level string no 正本 (英語): national / prefecture / municipality / financial。日本語別名 ( / 都道府県 / 市区町村 / 公庫) も API 側で正規化して受け付ける
funding_purpose string (repeat) no 資金用途 (例: 設備投資)
target_type string (repeat) no 対象者種別 (例: 認定新規就農者)
amount_min number no 助成上限の下限 (万円)
amount_max number no 助成上限の上限 (万円)
include_excluded bool no true で tier=X も含める (default false)
limit int no 1〜100 (default 20)
offset int no ページング (default 0)
fields enum no minimal / default / full。レスポンスサイズ切替 (default default)

fields 選択肢:

results[] の中身 目安サイズ (1 row) 用途
minimal unified_id / primary_name / tier / prefecture / authority_name / amount_max_man_yen / official_url の 7 キーのみ ~150-300 B リスト表示、クイックフィルタ、MCP tool の中間結果
default (省略時) Program 全フィールド (今までと完全互換) ~500-800 B 通常の統合
full Program + enriched (A-J 全次元) + source_mentions + lineage (source_url / source_fetched_at / source_checksum)。enriched / source_mentions は null でもキーが必ず存在 ~3-50 KB (enriched 次第) 単一制度の深い読み込み、エージェントのリサーチ

minimal / full は追加扱い。default のスキーマは破壊的変更せずに維持する。

Response (SearchResponse):

{
  "total": 153,
  "limit": 20,
  "offset": 0,
  "results": [
    {
      "unified_id": "string",
      "primary_name": "string",
      "aliases": ["string"],
      "authority_level": "national",
      "authority_name": "経済産業省",
      "prefecture": null,
      "municipality": null,
      "program_kind": "補助金",
      "official_url": "https://...",
      "amount_max_man_yen": 450,
      "amount_min_man_yen": 30,
      "subsidy_rate": 0.5,
      "trust_level": "high",
      "tier": "A",
      "coverage_score": 0.82,
      "gap_to_tier_s": ["J_statistics"],
      "a_to_j_coverage": {"A_basics": true, "B_target": true},
      "excluded": false,
      "exclusion_reason": null,
      "crop_categories": [],
      "equipment_category": null,
      "target_types": ["中小企業"],
      "funding_purpose": ["設備投資"],
      "amount_band": "100-500",
      "application_window": {"start": "2026-04-01", "end": "2026-06-30"}
    }
  ]
}

Response example at fields=minimal:

{
  "total": 153,
  "limit": 20,
  "offset": 0,
  "results": [
    {
      "unified_id": "UNI-keiei-kaishi-shikin",
      "primary_name": "経営開始資金",
      "tier": "S",
      "prefecture": null,
      "authority_name": "農林水産省",
      "amount_max_man_yen": 1500,
      "official_url": "https://www.maff.go.jp/j/new_farmer/..."
    }
  ]
}

Response example at fields=full: default と同じ results[i] に加え、各 row に enriched (A-J 次元) / source_mentions (list of {url, fetched_at}) / source_url / source_fetched_at / source_checksum が必ず入る (値が null でもキーは存在)。

Example:

# default shape
curl -H "X-API-Key: jpintel_..." \
  "https://api.autonomath.ai/v1/programs/search?q=IT導入&tier=S&tier=A&limit=5"

# minimal — list rendering / quick filter
curl -H "X-API-Key: jpintel_..." \
  "https://api.autonomath.ai/v1/programs/search?q=IT導入&limit=20&fields=minimal"

ソート: FTS を使った場合は rank 順、それ以外は tier (S→A→B→C→X) → primary_name。


GET /v1/programs/{unified_id}

単一制度の詳細取得。enriched (A-J 次元の詳細) と source_mentions を含む。

認証: 任意

Path parameters:

name type required description
unified_id string yes 制度 ID

Query parameters:

name type required description
fields enum no minimal / default / full。レスポンスサイズ切替 (default default)

fields 選択肢 (/v1/programs/{unified_id}):

中身 備考
minimal 7-key whitelist (unified_id / primary_name / tier / prefecture / authority_name / amount_max_man_yen / official_url) 詳細画面では通常使わないが、埋め込み UI の軽量表示に
default (省略時) ProgramDetail (Program + enriched + source_mentions + lineage) — 従来と完全互換 通常の統合
full 同上。ただし enriched / source_mentions / lineage 3 キーは null でも必ず key が存在する契約に揃う 「null = 調査済で空」「key なし = 旧サーバー」を区別する必要がある AI agent 向け

Response (ProgramDetail): SearchResponse.results[] と同じ構造 + 以下:

{
  "...Program fields...": "...",
  "enriched": {
    "A_basics": {"...": "..."},
    "B_target": {"...": "..."},
    "J_statistics": null
  },
  "source_mentions": [
    {"url": "https://...", "fetched_at": "2026-04-15T10:00:00Z", "confidence": 0.9}
  ]
}

Example:

# default (current behavior, unchanged)
curl -H "X-API-Key: jpintel_..." \
  "https://api.autonomath.ai/v1/programs/keiei-kaishi-shikin"

# minimal — just the headline fields
curl -H "X-API-Key: jpintel_..." \
  "https://api.autonomath.ai/v1/programs/keiei-kaishi-shikin?fields=minimal"

# full — enriched / source_mentions / lineage keys guaranteed present
curl -H "X-API-Key: jpintel_..." \
  "https://api.autonomath.ai/v1/programs/keiei-kaishi-shikin?fields=full"

エラー: 存在しない ID は 404 Not Found


POST /v1/programs/batch

最大 50 件の unified_id をまとめて解決する。GET /v1/programs/{unified_id} を N 回叩く代わりに 1 リクエストで済ませる用途 (agent が search_programs の 20 件候補を全件 enrich したい等)。

認証: 任意 (未認証は free tier)

Request body (BatchGetProgramsRequest):

{"unified_ids": ["UNI-keiei-kaishi-shikin", "UNI-koyo-shuno-shikin", "UNI-test-a-1"]}
field type required description
unified_ids string[] yes 1〜50 件の制度 ID。重複は自動 dedupe (最初の出現順を保持)

バリデーション:

  • unified_ids が空配列 → 422 Unprocessable Entity
  • 50 件超 → 422 Unprocessable Entity
  • unified_ids の cap は 50 件 (paging は提供しない。50 超の caller は client 側で chunk する)

Response (BatchGetProgramsResponse):

{
  "results": [
    {
      "unified_id": "UNI-keiei-kaishi-shikin",
      "primary_name": "経営開始資金",
      "tier": "S",
      "enriched": {"A_basics": {"...": "..."}},
      "source_mentions": [{"url": "https://...", "fetched_at": "2026-04-15T..."}],
      "source_url": "https://...",
      "source_fetched_at": "2026-04-22T...",
      "source_checksum": "638865704e10041c",
      "...": "..."
    }
  ],
  "not_found": ["UNI-typo-1"]
}
field type description
results ProgramDetail[] 各要素は GET /v1/programs/{id}?fields=full と同じ shape。enriched / source_mentions / lineage 3 キーは null でも必ず存在。dedupe 後の入力 unified_ids 順を保存
not_found string[] DB に該当行がなかった ID。部分成功扱いなので 404 ではなく 200 で not_found[] に入る

重要な契約:

  • 順序保証: results[i].unified_id は dedupe 後の unified_ids[i] と一致する。
  • 部分成功: 50 件のうち 3 件が存在しなくても 200 が返り、3 件は not_found[] に入る。全件無しでも {"results": [], "not_found": [...]} で 200。
  • 例外は 500: not_found は「DB に存在しない」ケースだけ。JSON decode 失敗等の例外は batch 全体が 500 で落ちる (部分成功を暗黙に隠さない方針)。
  • paging なし: 50-cap がそのまま paging。50 超の ID リストは client 側で chunk(ids, 50) してループする。

Rate limit: 現在は batch 全体で 1 request 扱い (free: 100/day のうち 1 消費、paid: metered で 1 req 分 ¥0.5 を usage report)。将来的に N 件 × N 単位の課金に移行予定 (launch 後、src/jpintel_mcp/api/programs.pybatch_get_programs TODO 参照)。

Example:

curl -X POST https://api.autonomath.ai/v1/programs/batch \
  -H "X-API-Key: jpintel_..." \
  -H "Content-Type: application/json" \
  -d '{"unified_ids":["UNI-keiei-kaishi-shikin","UNI-koyo-shuno-shikin"]}'
# SDK パターン: search -> batch で 20 件 enrich
import httpx

with httpx.Client(
    base_url="https://api.autonomath.ai",
    headers={"X-API-Key": "jpintel_..."},
) as client:
    search = client.get(
        "/v1/programs/search",
        params={"q": "IT導入", "fields": "minimal", "limit": 20},
    ).json()
    ids = [row["unified_id"] for row in search["results"]]
    detail = client.post(
        "/v1/programs/batch",
        json={"unified_ids": ids},
    ).json()
    for row in detail["results"]:
        print(row["unified_id"], row["primary_name"], row.get("enriched"))
    if detail["not_found"]:
        print("missing:", detail["not_found"])

Exclusions

制度の排他ルール関連。概念は exclusions.md

GET /v1/exclusions/rules

排他ルール全件を返す (現在 35 件: 農業核心 22 + 非農業 IT導入・持続化・M&A 等 13)。

認証: 任意

Response (list[ExclusionRule]):

[
  {
    "rule_id": "agri-001",
    "kind": "mutex",
    "severity": "absolute",
    "program_a": "keiei-kaishi-shikin",
    "program_b": "koyo-shuno-shikin",
    "program_b_group": [],
    "description": "経営開始資金と雇用就農資金は同時受給不可",
    "source_notes": "MAFF 要綱 第3条",
    "source_urls": ["https://www.maff.go.jp/..."],
    "extra": {}
  }
]

フィールド:

field type description
rule_id string ルール一意 ID
kind string mutex / prerequisite / conditional_reduction など
severity string | null absolute / conditional など
program_a string | null 片側の制度 ID
program_b string | null もう片側の制度 ID (または group を使用)
program_b_group string[] 複数制度が相手の場合のグループ
description string | null 人間可読な説明
source_notes string | null 出典の簡易メモ
source_urls string[] 一次資料 URL
extra object 追加メタ

POST /v1/exclusions/check

候補制度セットに対して排他ルールが triggered するか判定する。

認証: 任意

Request body (ExclusionCheckRequest):

{
  "program_ids": ["keiei-kaishi-shikin", "koyo-shuno-shikin"]
}
field type required description
program_ids string[] yes (1 件以上) 制度 ID 配列。重複は自動 dedup

Response (ExclusionCheckResponse):

{
  "program_ids": ["keiei-kaishi-shikin", "koyo-shuno-shikin"],
  "hits": [
    {
      "rule_id": "agri-001",
      "kind": "mutex",
      "severity": "absolute",
      "programs_involved": ["keiei-kaishi-shikin", "koyo-shuno-shikin"],
      "description": "同時受給不可",
      "source_urls": ["https://www.maff.go.jp/..."]
    }
  ],
  "checked_rules": 35
}

判定ロジック:

  • kind == "mutex" は 2 件以上 selected に含まれると hit
  • kind == "prerequisite" は 1 件でも含まれば hit (順序違反候補としてレポート)

エラー: program_ids が空なら 400 Bad Request

Example:

curl -X POST -H "X-API-Key: jpintel_..." \
  -H "Content-Type: application/json" \
  -d '{"program_ids":["keiei-kaishi-shikin","koyo-shuno-shikin"]}' \
  https://api.autonomath.ai/v1/exclusions/check

Meta

GET /meta

データセット全体の統計。ダッシュボード表示や health check 用途。

認証: 任意

Response (Meta):

{
  "total_programs": 6771,
  "tier_counts": {"S": 59, "A": 525, "B": 3297, "C": 2421, "X": 469},
  "prefecture_counts": {"青森県": 42, "_none": 4311, "...": "..."},
  "exclusion_rules_count": 35,
  "last_ingested_at": "2026-04-22T09:00:00Z",
  "data_as_of": "2026-04-21"
}
  • prefecture_counts_none は prefecture=null (全国制度または未ラベル) のバケット
  • last_ingested_at は DB の最終 ingest 時刻, data_as_of は元データの基準日

Example:

curl https://api.autonomath.ai/meta

GET /healthz

Liveness probe。DB 接続のみ確認。

認証: 不要

Response:

{"status": "ok"}

GET /v1/ping

認証付き probe。/healthz は liveness (DB ping のみ) で key 検証をしないため、 「今この key で API に届くか + tier は何か」を 1 本で確認したい時に使う。

認証: 任意 (未認証は free 扱い)

Response:

{
  "ok": true,
  "authenticated": true,
  "tier": "paid",
  "server_time_utc": "2026-04-23T14:00:00Z",
  "server_version": "0.1.0",
  "rate_limit_remaining": null
}
field type description
ok bool 常に true (到達できた時点で)
authenticated bool 有効な key が提示されたか
tier string free / paid
server_time_utc string サーバー時刻 (UTC, YYYY-MM-DDTHH:MM:SSZ)
server_version string AutonoMath version
rate_limit_remaining int | null 本日の残り呼び出し数。paid (metered) は null (hard cap なし)

使用量への影響: /v1/ping は認証付き呼び出しのみ usage_events にカウントされる (heartbeat で無限に叩かれる濫用を抑止するため)。未認証呼び出しはカウントしない (per-IP の記録を持たないため)。頻繁に heartbeat したい用途では /healthz を推奨。

匿名時の rate_limit_remaining: 未認証時は free tier の上限値そのものが返る (per-IP 使用量を記録していないため、正確な残量を返せない)。

Example:

curl -H "X-API-Key: jpintel_..." https://api.autonomath.ai/v1/ping

Billing

Stripe 経由のサブスクリプション管理。詳細フローは getting-started.md

POST /v1/billing/checkout

Stripe Checkout セッションを作成して URL を返す。

認証: 不要

Request body:

field type required description
success_url string yes 決済後のリダイレクト先 (session_id を受け取るページ)
cancel_url string yes キャンセル時のリダイレクト先
customer_email string no Stripe に事前に渡すメールアドレス

tier フィールドは存在しない (pure metered、Price は 1 本: STRIPE_PRICE_PER_REQUEST 環境変数で指定)。

Response:

{"url": "https://checkout.stripe.com/...", "session_id": "cs_live_..."}

エラー: Stripe 未設定時は 503


POST /v1/billing/portal

Stripe Customer Portal URL を返す (サブスク変更・キャンセル・カード変更用)。

認証: 不要 (customer_id を body に渡す)

Request body:

{"customer_id": "cus_...", "return_url": "https://your-app.example.com/account"}

Response:

{"url": "https://billing.stripe.com/..."}

POST /v1/billing/keys/from-checkout

Checkout 成功後に API key を発行する。1 session につき 1 回のみ。

認証: 不要 (Stripe session 検証で認証)

Request body:

{"session_id": "cs_live_..."}

Response:

{"api_key": "jpintel_...", "tier": "paid", "customer_id": "cus_..."}

エラー:

  • 402 Payment Required — session が paid になっていない
  • 409 Conflict — 同 subscription で既に key 発行済み (rotation は /v1/billing/portal 経由)

POST /v1/billing/webhook

Stripe webhook 受け口。以下のイベントを処理:

  • customer.subscription.created — 初回サブスク時に API key を自動発行 (主経路)
  • invoice.paid — safety net として同じく key 発行 (subscription.created を取りこぼした場合)
  • customer.subscription.updated — 状態同期
  • customer.subscription.deleted — key の revoke (Free tier に戻る)
  • invoice.payment_failed — 支払い失敗の記録

認証: Stripe 署名 (stripe-signature header) で検証

Response: {"status": "received"}

エンドユーザーが直接叩くものではない。


Feedback

POST /v1/feedback

開発者向けの feedback 受け口。変なレスポンスを見つけた時・命名案がある時に、 GitHub issue を開く前に 1 POST で送れる軽量窓口。

認証: 任意 (未認証でも OK)。key を付ければ customer_id + tier が紐付く。

Request body (FeedbackRequest):

{
  "message": "search で 認定新規就農者 が Hit しない件",
  "rating": 3,
  "endpoint": "/v1/programs/search",
  "request_id": "abcd1234"
}
field type required description
message string yes 1〜4000 文字。自由記述
rating int no 1〜5 (満足度)
endpoint string no 関連エンドポイント (例: /v1/programs/search)
request_id string no x-request-id header の値など

Response (FeedbackResponse):

{"received": true, "feedback_id": 42}

Rate limit: 1 日あたり 10 件 per API key (認証時) または per IP hash (未認証時)。 超過時は 429 Too Many Requests

保存される情報:

  • message, rating, endpoint, request_id (上記入力)
  • 認証時: key_hash, customer_id, tier
  • ip_hash (raw IP は保存しない / HMAC-SHA256 with salt)
  • created_at (UTC ISO)

Example:

curl -X POST https://api.autonomath.ai/v1/feedback \
  -H "X-API-Key: jpintel_..." \
  -H "Content-Type: application/json" \
  -d '{"message":"tier=X の理由が見えづらい","rating":4}'

エラー形式 (Error format)

FastAPI 標準:

{"detail": "エラー理由"}
code 意味
400 リクエスト不正 (params / body)
401 認証失敗 / revoked key
402 Stripe 決済未完了
404 リソース無し
409 重複操作 (key 発行済み等)
429 rate limit 超過
503 Stripe 未設定など運用外状態

Admin (internal)

運営者向けの funnel / cohort / error endpoint 群 (/v1/admin/*) は非公開。別 key (ADMIN_API_KEY) で認証し、OpenAPI export (docs/openapi/v1.json, SDK 生成) には含めない (include_in_schema=False)。SLA / versioning policy の対象外で、/v1/* 安定契約の一部ではない

仕様: 内部 docs/_internal/admin_api.md 参照 (non-public、repo-only)。

関連

  • mcp-tools.md — 同じ機能を MCP tool として叩く
  • exclusions.md — 排他ルールの概念
  • pricing.md — tier 別制限
  • docs/_internal/admin_api.md — 内部用 admin endpoint (non-public、repo-only)
  • サンプル集 — 8 本の runnable サンプル (Python 4 + TypeScript 4, 各ファイル 50-150 行)