業務システム

freee APIとは:会計APIの認可・事業所IDと取引登録をPythonで実装する手順と上限

freee APIとは:会計APIの認可・事業所IDと取引登録をPythonで実装する手順と上限

freee APIは、freee会計やfreee人事労務などのデータを、自社のシステムからHTTPで読み書きするためのAPIです。この記事では、中心となるfreee会計APIを対象に、OAuth 2.0による事業所単位の認可、6時間で切れるアクセストークンと1回しか使えないリフレッシュトークンの扱い、Pythonでの取引の登録と一覧の取得、プランごとに決まる1日の呼び出し上限までを、コード例付きで説明します。公式リファレンスでは別々のページに分かれている「実装で詰まる箇所」を、1本にまとめました。仕様と数値は2026年11月時点の公式ドキュメントと公式OpenAPI定義に基づきます。

まとめ:freee APIで会計連携を作る前に決める認可の単位と呼び出し上限

freee会計APIの認証はOAuth 2.0だけです。認可URLにprompt=select_companyを付けると、利用者が選んだ1つの事業所にだけアクセスできるトークンが発行され、応答に事業所IDcompany_idが入ります。ほぼすべてのAPIでこのIDが必須なので、トークンと一緒に保存します。

詰まりやすいのは次の4点です。アクセストークンは6時間、リフレッシュトークンは90日で、リフレッシュトークンは1回しか使えないこと。公式FAQが、前のアクセストークンが切れる前に更新するよう求めていること。取引と振替伝票は別のAPIで、売掛・買掛のレポートに載るのは取引だけであること。403が「呼び出しすぎ」と「権限不足」の2つの意味で返ること。

上限は事業所とアプリの組み合わせごとに1日3,000回から10,000回で、契約プランで決まります。冪等キーの仕組みは無いため、再実行で同じ取引が2件できない設計は呼び出し側で作ります。

freee会計APIの全体像と操作できる範囲・エンドポイント・プラン差

取引・振替伝票・口座明細・試算表など107本のエンドポイントの範囲

freeeが公開している公式のOpenAPI定義(freee-api-schema)には、会計APIのパスが107本定義されています。業務でよく使うものを区分ごとに並べると次のとおりです。

区分 パス 主な操作
取引 deals 収入・支出の作成、支払行の追加
振替伝票 manual_journals 貸借を指定した伝票の作成
口座明細 wallet_txns 明細の登録と取引への変換
帳票 reports 試算表(BS・PL)と総勘定元帳
仕訳帳 journals ファイル出力の依頼と取得
マスタ account_items ほか 勘定科目・税区分・取引先・部門・品目

パスはすべてhttps://api.freee.co.jp/api/1/の後ろに続きます。このOpenAPI定義はGitHubからそのまま取得できるので、型の生成やPostmanのコレクション作成に使えます。画面で見るなら会計APIリファレンスが同じ内容です。

総勘定元帳と固定資産台帳のAPIが上位プランに限られるプラン差

freee会計APIは、Web版で使える機能がAPIでも使えるという原則です。経費精算を使える契約なら、経費精算のAPIも呼べます。例外として、公式OpenAPI定義の説明欄には次の2つが明記されています。

  • 総勘定元帳API:法人アドバンスプラン、法人エンタープライズプラン(旧プロフェッショナル・旧エンタープライズを含む)のみ
  • 固定資産台帳API:法人エンタープライズプラン(旧エンタープライズを含む)のみ
  • セグメントタグのパラメータ:法人アドバンスプラン以上(セグメント2・3はアドバンスとエンタープライズ)

対象外のプランで呼ぶと401が返り、エラーコードはfreee_plan_limitです。顧客ごとに契約プランが違う連携を作るときは、プラン差で落ちる機能を要件定義の段階で洗い出しておきます。

使える機能と上限は接続先の事業所の契約で決まり、開発環境は無料

API経由で使える機能と上限は、接続先の事業所が契約しているfreee会計のプランで決まります。開発中の動作確認には、開発用テスト環境の案内にある「開発用テスト事業所」が無料で作れる仕組みです。事業形態とプランを選んで作れるので、法人アドバンス相当の機能も本番の契約なしで試せます。

注意点が1つあります。作成から90日以上たち、過去90日間にアプリ経由のAPI実行が無いテスト事業所は、アプリごと削除対象になり、復旧できません。開発が止まる期間がある案件では、テストデータの作成手順をスクリプトに残しておくと作り直しが楽です。

OAuth 2.0の認可を事業所単位で通すアプリ登録とトークン管理の実装

プライベートは5事業所、パブリックは既定20事業所というアプリ種別の差

アプリはfreeeアプリストアの開発者画面で作ります。アプリについての公式説明によると、種別は2つです。

項目 プライベートアプリ パブリックアプリ
想定する使い方 特定の事業所だけで使う 複数の事業所へ配布する
接続できる事業所数 5事業所まで 既定20事業所まで
上限の解除 不可 ストア公開か上限変更の申請
アプリストア掲載 不可 審査を経て可能
銀行明細の取得 申請不要 申請が必要

自社の会計と社内システムをつなぐだけならプライベートで足ります。会計事務所が顧問先を6社以上つなぐ、あるいは自社サービスとして配る場合はパブリックを選びます。上限変更の申請は、接続事業所が15に達するまで出せない点も計画に入れてください。

select_company指定で1事業所だけを認可させる認可URLとトークン取得

認可はOAuth 2.0の認可コードフローで行います。公式の認可の説明にあるとおり、認可エンドポイントはhttps://accounts.secure.freee.co.jp/public_api/authorize、トークンエンドポイントは同じホストの/public_api/tokenです。APIを呼ぶホストapi.freee.co.jpとは別なので、設定値を取り違えないようにします。

# 1. ブラウザで開く(prompt=select_company で事業所選択画面を出す)
https://accounts.secure.freee.co.jp/public_api/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&state=${STATE}&prompt=select_company

# 2. リダイレクト先に付いた code をトークンに交換する
curl -s -X POST "https://accounts.secure.freee.co.jp/public_api/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "code=${AUTH_CODE}" \
  -d "redirect_uri=${REDIRECT_URI}"
# 応答例: {"access_token":"...","expires_in":21600,"refresh_token":"...","company_id":123, ...}

事業所の選択についての説明では、prompt=select_companyを付ける方式が推奨で、付けない方式(アカウントの全事業所を認可する)は将来廃止予定とされています。付けない方式でストアに出すと、事業所選択を自前で実装していない限り審査で承認されません。新規の実装は最初から付ける形で作ってください。認可フローの考え方はOAuth 2.0の仕組みと認可フローの解説で扱っています。

6時間のアクセストークンと90日で1回限りのリフレッシュトークンの更新

トークンの有効期限についてのFAQによると、アクセストークンは6時間、リフレッシュトークンは90日有効です。1つのリフレッシュトークンで2回アクセストークンを取ることはできず、更新のたびに返る新しいリフレッシュトークンを保存し直します。

実装上の落とし穴は2つあります。1つは、同じFAQが401のチェック項目として「前のアクセストークンが有効な間に更新する」ことを挙げている点です。401を受けてから更新する作りだと、この条件を外れることがあるため、期限の少し前に更新する作りにします。もう1つは、再試行による二重の更新。エラーレスポンスの説明では、更新後に古いトークンを使うとinvalid_grantになるとされています。

# pip install requests
import os
import time

import requests

TOKEN_URL = "https://accounts.secure.freee.co.jp/public_api/token"
BASE = "https://api.freee.co.jp/api/1"


def refresh(store) -> dict:
    """store は DB のトークン行(排他ロックを取った状態で渡す想定)"""
    # 期限の30分前を過ぎたら更新する(アクセストークンが有効なうちに更新する)
    if time.time() < store["expires_at"] - 1800:
        return store
    r = requests.post(TOKEN_URL, data={
        "grant_type": "refresh_token",
        "client_id": os.environ["FREEE_CLIENT_ID"],
        "client_secret": os.environ["FREEE_CLIENT_SECRET"],
        "refresh_token": store["refresh_token"],
    }, timeout=10)
    r.raise_for_status()  # 401 invalid_grant は使用済みトークンの再利用を疑う
    body = r.json()
    # 新しいリフレッシュトークンは1回限り。取得と保存を同じトランザクションで確定させる
    store.update(
        access_token=body["access_token"],
        refresh_token=body["refresh_token"],
        expires_at=time.time() + body["expires_in"],  # 21600秒=6時間
    )
    return store

複数のワーカーが同じ事業所のトークンを同時に更新すると、遅れたほうが使用済みのリフレッシュトークンを送って失敗します。トークン行に排他ロックを取ってから更新し、保存が終わるまで他の処理を待たせます。90日のあいだ1回も更新しなかった事業所は再認可が必要になるので、取引の少ない事業所にも定期的な更新ジョブを回しておくのが安全策です。

取引の登録と一覧取得の実装:事業所IDから勘定科目・税区分まで

認可した事業所のcompany_idをトークンと保存しクエリと本文に付ける

freee会計APIは、事業所一覧の取得などを除き、どの事業所のデータかをcompany_idで指定します。GETではクエリに、POSTやPUTではJSON本文に入れます。prompt=select_companyで認可した場合、トークン取得の応答に入っているcompany_idがそのまま使う値で、選ばれなかった事業所の詳細には触れません。

存在しない、または削除済みの事業所IDを指定すると、401のエラーコードcompany_not_foundが返ります。複数の事業所を扱うシステムでは、事業所IDとトークンを同じ行に保存し、処理の入り口で取り出す形にしておくと、別の事業所へ書き込む事故を防げます。兄弟製品のマネーフォワード APIの実装手順は、APIキー認証で事業所番号を呼び出しごとに指定する方式なので、両方に対応する連携基盤では事業所の持ち方を分けた設計が必要です。

取引作成の必須項目は4つで明細は最大100行、金額は税込の円で送る

取引(収入・支出)はPOST /api/1/dealsで作ります。公式OpenAPI定義の必須項目は、事業所IDcompany_id、発生日issue_date、収支区分type(incomeかexpense)、明細行detailsの4つです。明細行は最大100行で、各行に税区分コードtax_codeと、税込・円単位の金額amountが必須になります。

def call(method: str, path: str, token: str, **kw):
    r = requests.request(method, BASE + path,
                         headers={"Authorization": f"Bearer {token}"},
                         timeout=30, **kw)
    r.raise_for_status()
    return r.json()


token, company_id = store["access_token"], store["company_id"]

# 勘定科目と税区分は名前ではなくIDとコードで送る。先に対応表を作る
items = call("GET", "/account_items", token, params={"company_id": company_id})["account_items"]
acc = {a["name"]: a["id"] for a in items}
TAX_CODE_SALES = int(os.environ["FREEE_TAX_CODE_SALES"])  # 事業所ごとに値を確認して設定する

deal = {
    "company_id": company_id,
    "issue_date": "2026-11-02",
    "type": "income",
    "due_date": "2026-11-30",
    "ref_number": "SO-2026-0042",  # 管理番号。元データのキーを入れて照合に使う
    "details": [{
        "account_item_id": acc["売上高"],
        "tax_code": TAX_CODE_SALES,  # 税区分APIで事前に確認した課税売上のコード
        "amount": 110000,          # 税込・円
        "description": "11月分 保守料",
    }],
}
created = call("POST", "/deals", token, json=deal)
print(created["deal"]["id"])  # 更新・削除で使うID。自社DBに保存しておく

税区分コードは、GET /api/1/taxes/companies/{company_id}でその事業所が使える一覧を取ってから決めます。コード例では確認済みの値を環境変数で渡していますが、税率の変更に合わせて見直せるよう、設定値として外に出しておくのが無難です。取引先コードや勘定科目コードを使いたい場合は、事業所の設定でコード利用を有効にする必要があり、IDとコードを同時には指定できません。

取引と振替伝票の使い分けは売掛買掛レポートに載せるかどうかで判断

貸借を自分で組む仕訳はPOST /api/1/manual_journals(振替伝票)で作ります。公式OpenAPI定義の注意点には、振替伝票は売掛・買掛レポートに反映されず、債権・債務の登録には取引APIを使うよう書かれています。貸借行は合計100行までで、貸方と借方の合計が一致していることが条件です。

判断の基準は単純です。請求や支払の消し込みを追う売上・仕入は取引で登録する。減価償却や科目の振り替えのように債権・債務を伴わないものは振替伝票で登録する。販売管理から売上を流す連携で振替伝票を使うと、入金の消し込みがfreeeの画面でできなくなり、経理担当者の手作業が残ります。仕訳の起点をどこに置くかは経理システムと会計システムの違いの解説でも整理しています。

一覧取得はlimit最大100件で、仕訳帳は非同期のファイル出力で取る

GET /api/1/dealsの1回の取得件数limitは既定20件、最大100件で、offsetをずらして次を取ります。発生日start_issue_dateとend_issue_dateで範囲を絞れます。

offset, rows = 0, []
while True:
    res = call("GET", "/deals", token, params={
        "company_id": company_id,
        "start_issue_date": "2026-04-01", "end_issue_date": "2026-11-30",
        "limit": 100, "offset": offset,
    })
    rows += res["deals"]
    if len(res["deals"]) < 100:
        break
    offset += 100
print(len(rows), "件")

1万件の取引を取ると100回の呼び出しになり、後述する1日の上限を食います。会計期間の仕訳をまとめて取りたいときは、仕訳帳のGET /api/1/journalsを使います。こちらはファイル作成を依頼するだけのAPIで、返った受付IDで/journals/reports/{id}/statusを確認し、uploadedになってから/downloadで取得する2段階です。文字コードは指定しないとShift_JISになるので、encoding=utf-8を付けておきます。

本番運用で詰まる上限:1日のAPIコール数と403・429・二重登録

事業所とアプリごとに1日3,000〜10,000回というプラン別の呼び出し上限

公式OpenAPI定義の説明欄には、事業所とアプリケーションの組み合わせごとの1日の上限が載っています。

freee会計のプラン 1日の上限
法人エンタープライズプラン 10,000回
法人アドバンスプラン(旧プロフェッショナル) 5,000回
上記以外(個人のプランを含む) 3,000回

3,000回は、取引を1件ずつ登録すれば1日3,000件で尽きる数です。月末に数千件をまとめて送る処理では、明細を1件の取引に複数行まとめる、マスタの取得を起動時の1回に絞る、といった呼び出し回数の節約を最初から設計に入れます。同じ事業所に複数のアプリをつないでいる場合、上限はアプリごとに数えられます。

過度のアクセスで返る403と権限不足の403を見分けて10分待つ判断

freee会計APIの呼び出しすぎは、一般的な429ではなく403で返ります。公式OpenAPI定義の説明では、一定期間に過度のアクセスを検知すると403でアクセスを制限し、10分程度で解除されるとしています。一方、アプリの権限設定に無いエンドポイントを呼んだときも403で、メッセージは「このアプリケーションにはアクセス権限がないエンドポイント」である旨の文言です。

両者を同じ扱いにすると、権限不足を10分待って再試行し続ける、あるいは制限中に権限設定を疑って時間を失う、という失敗が起きます。本文のメッセージで分岐し、権限不足ならすぐに失敗として通知、それ以外の403は10分以上空けてから再開する作りが安全です。429が返るのは試算表などの/reports(毎秒10回まで)と証憑のダウンロード/receipts/{id}/download(毎秒3回まで)で、応答ヘッダx-ratelimit-resetにリセット時刻が入ります。待ち方の設計はAPIレート制限の解説とリトライパターンと指数バックオフの解説が参考になります。

再送で同じ取引が2件できる問題を管理番号と自社DBの対応表で防ぐ

取引作成のAPIには、重複を防ぐ冪等キーがありません。タイムアウトで応答を受け取れなかった処理をそのまま再送すると、同じ取引が2件できます。取引一覧の絞り込み条件も、取引先・勘定科目・発生日などで、管理番号ref_numberでは検索できません。

  1. 自社DBに「元データのキーと取引ID」の対応表を作り、送信前に状態を「送信中」で登録する
  2. 201が返ったら取引IDを書き込み、状態を「完了」にする
  3. 「送信中」のまま残った行は、発生日で取引一覧を取り、ref_numberに入れた元データのキーで照合してから再送するか決める

照合のために、管理番号には元データのキーを必ず入れます。考え方は冪等性と担保方法の解説にまとめています。

freee API連携を自社開発すべき条件と既製の連携で済ませる場面

販売管理からの売上自動登録と複数事業者の横断集計なら自社開発

APIを使う開発に進む価値があるのは、次のどちらかが要件にある場合です。1つは、販売管理や受発注システムの確定データから、勘定科目・税区分・取引先まで決めた取引を毎日自動で登録し、入金の消し込みまでfreee上で回したい場合。もう1つは、会計事務所やグループ会社のように、複数の事業所の試算表や取引を1か所に集めたい場合です。後者はプライベートアプリの5事業所の上限にすぐ当たるため、パブリックアプリの申請と事業所ごとのトークン管理まで含めた設計が要ります。会計事務所側の使い方は税理士が使う会計ソフトと連携方式の解説でも扱っています。

CSVインポートや自動登録ルールで足りる場面と開発会社へ相談する目安

月に数十件の取引を取り込むだけなら、APIを使う開発は過剰です。freee会計の取り込み機能と明細の自動登録ルールで足り、トークンの更新や上限の管理も要りません。勘定科目の決め方とルール設計は会計ソフトの勘定科目と自動仕訳ルールの設計、freee以外のバックオフィスSaaSと比べている段階ならバックオフィスSaaSの比較と連携の判断軸を先に読むと手戻りがありません。

一方、基幹システムとの双方向の連携、数万件規模の過去データの移行、複数事業所をまたぐ集計のように、認可の単位や1日の上限、失敗時の再実行まで設計する必要がある場合は、要件定義の段階から開発会社に入ってもらうと安全です。一創のAPI開発・システム連携サービスでは、会計SaaSと社内システムの連携を、要件整理から運用まで受託しています。REST APIの連携全般の手順はAPI連携の実装方法の記事も参考になります。

freee APIの料金・個人利用・MCP連携でよくある質問

freee APIを使い始める実装者や担当者から出やすい質問に、公式ドキュメントの記載をもとに答えます。

freee APIは無料で使えますか?

開発を始めるまでは費用がかかりません。freeeアカウントを持っていなければ無料の開発者向けアカウントを作れ、開発用テスト事業所も無料で作成できます。本番で使える機能と1日の呼び出し上限は、接続先の事業所が契約しているfreee会計のプランで決まるので、費用として見るべきはAPIではなくそのプランの料金です。総勘定元帳APIのようにプランが足りないと呼べないものもあり、その場合はfreee_plan_limitのエラーが返ります。

個人事業主でもfreee APIを使えますか?

使えます。個人向けのfreee会計を契約していれば、法人と同じ手順でアプリを作り、自分の事業所を認可できます。1日の上限は法人エンタープライズとアドバンス以外のプランと同じ3,000回で、個人の記帳を自動化する用途には十分な回数です。自分の事業所だけで使うなら、アプリはプライベートで作れば審査も要りません。

freee APIとマネーフォワード APIの違いは何ですか?

大きな違いは認証と事業所の指定方法です。freeeはOAuth 2.0だけで、認可時に選んだ事業所のIDをトークンと一緒に持つ方式。マネーフォワード クラウド会計APIはOAuth 2.0に加えてAPIキー認証があり、APIキーでは事業所番号を呼び出しごとに指定します。上限もfreeeは1日の回数、マネーフォワードは毎秒の回数で決まります。詳しくはマネーフォワード APIの認証方式と仕訳登録の解説を参照してください。

AIエージェントからfreeeを操作するfreee-mcpとAPIの関係は?

freeeは、AIエージェントから会計・人事労務・請求書などのAPIを操作するための公式MCPサーバーfreee-mcpをGitHubで公開しています。中で呼んでいるのはこの記事で扱ったfreee APIなので、事業所の選択やプラン別の上限はそのまま当てはまると考えてください。利用者向けのChatGPTアプリとの違いはfreeeのChatGPTアプリとfreee-mcp連携の違いで解説しています。

取引が登録されたことを自社システムで即時に受け取れますか?

2026年11月時点ではできません。会計Webhookの概要で通知の対象になっているのは、各種申請・経費精算・支払依頼の作成と更新だけで、取引や振替伝票は含まれていません。Webhook自体もβ版と明記されています。取引の変更を拾うには一覧APIを定期的に呼ぶことになるため、発生日の範囲を前回の取得以降に絞り、1日の上限を食わない間隔で回します。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.29 テックブログ ソニー生命の不正アクセス:38.5万件の対象確認と窓口、停止中の手続き
  2. 2026.10.31 テックブログ osinaの情報漏洩:約23万人の対象確認とSNS連携の解除、分析ツールへ渡すデータの絞り方
  3. 2026.10.31 テックブログ 松屋の不正アクセス:237万件の対象確認と窓口、漏れたパスワードの守り方
  4. 2026.11.01 テックブログ RAGTAGの情報漏洩:延べ約120万件の対象項目と会員の備え、侵入から検知まで11日の意味
  5. 2026.05.18 テックブログ マネーフォワードで連携できない・失敗するときの対処法|エラー別の原因と再連携のやり方

RELATED POSTS 関連記事

目次