qbo について
qboは、QuickBooks Onlineの会計処理を自動化する開発者やエージェント向けのコマンドラインツールです。OAuth認証とJSON出力に対応し、レコード、レポート、添付ファイル、取引を操作できます。
主な機能
- 01OAuth認証と資格情報の安全な保存
- 02レコードの一覧、検索、作成、更新
- 03添付ファイルと取引PDFの操作
- 04コマンドスキーマとJSON終了コードの確認
活用シーン
- 01スクリプトで顧客や請求書のデータを取得
- 02顧客作成から請求、支払いまでのワークフロー
- 03ドライランと確認を使った取引の無効化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ voska/ qbo-cli --skill qboインストール後、Claude Code で/qboを入力して読み込まれたか確認します。
同梱ファイルreferences/COMMANDS.md
詳細
qbo — QuickBooks Online CLI
インストール
# macOS / Linux
brew install voska/tap/qbo
# Scoop (Windows)
scoop bucket add voska https://github.com/voska/scoop-bucket && scoop install qbo
# Go (any platform)
go install github.com/voska/qbo-cli/cmd/qbo@latest
# Binary: https://github.com/voska/qbo-cli/releases
認証情報の取得
OAuth 認証情報を取得するには、Intuit Developer アカウントと QuickBooks アプリが必要です。
- https://developer.intuit.com でサインアップし、ダッシュボードからアプリを作成します。
- プラットフォームとして QuickBooks Online and Payments を選択します。
- Keys & credentials で Client ID と Client Secret を確認します。
- Redirect URI を追加します(以下を参照)。
詳しい手順については、Intuit の OAuth 2.0 ガイドを参照してください。
Redirect URI のオプション
Sandbox では http://localhost:8844/callback を使用できます。Intuit ポータルに登録するだけで、qbo auth login がすべて自動的に処理します。
Production では localhost を使用できません。以下の 3 つの方法があります。
- トンネル/ファネルアドレス — ドメイン(例:
https://auth.yourdomain.com)からマシンへルーティングします。これをリダイレクト URI として登録します。--redirect-uriを使用するか、QBO_REDIRECT_URIを設定します。 - 同じマシンでログイン — エージェントを実行するマシンでブラウザーが使える場合は、トンネルを使用すると localhost コールバックを利用できます。
- 名前解決されないドメイン — 所有する任意のドメイン(例:
https://yourdomain.com)をリダイレクト URI として登録します。認証後、ブラウザーは URL に?code=...&realmId=...&state=...を付けてそのドメインにリダイレクトします。ブラウザーから完全な URL をコピーし、qbo auth loginに貼り付けます(またはエージェントに渡して手動で交換します)。
セットアップ
# Store app-level OAuth client credentials in the system keychain (one time).
# After this, no QBO_CLIENT_ID/SECRET env vars are needed for any command.
qbo auth set-client --client-id your_client_id --client-secret your_client_secret
# Sandbox — uses localhost callback automatically
qbo auth login --sandbox
# Production — specify your redirect URI
qbo auth login --redirect-uri https://yourdomain.com
# Or set it as env var / config so you don't need the flag every time
export QBO_REDIRECT_URI=https://yourdomain.com
qbo auth login
# Print the URL without opening a browser (useful for agents/remote)
qbo auth login --manual
localhost 以外のリダイレクト URI の場合、qbo auth login は認証 URL を表示し、認証後にコールバック URL を貼り付けるよう求めます。
トークンとクライアント認証情報(qbo auth set-client の実行後、または最初の qbo auth login の後)は、システムのキーチェーン(macOS Keychain、Windows Credential Manager)に保存されます。利用できない場合は、ファイルベースの ~/.config/qbo/tokens/ が使われます。認証情報は、環境変数(QBO_CLIENT_ID/QBO_CLIENT_SECRET)→ キーチェーン → config.json の優先順位で解決されます。そのため環境変数も引き続き使用でき、設定するとキーチェーンより優先されます。ログインキーチェーンにアクセスできないヘッドレスホストでは、QBO_KEYRING_BACKEND=file を設定すると、代わりに暗号化ファイルのバックエンドが使われます。
確認
認証後、すべてが正常に動作することを確認します。
qbo auth status
qbo company info --sandbox --json
「no company ID」が表示された場合は、export QBO_COMPANY_ID=<realm_id> または qbo company switch <realm_id> を設定します。
トラブルシューティング
| 問題 | 解決方法 |
|---|---|
no company ID | export QBO_COMPANY_ID=<realm> または qbo company switch <realm> |
Production エンドポイントでの ApplicationAuthorizationFailed | --sandbox を使用するか、Production の会社でアプリを再認証します |
| OAuth state の不一致 | qbo auth login を再起動し、新しく生成された URL を使用します |
| トークンの有効期限切れ | qbo auth refresh を実行するか、qbo auth login を再実行します |
レスポンスの構造
QBO はすべてのレスポンスをラップします。以下の形式を確認してください。
list/queryは{"QueryResponse": {"Invoice": [...], "startPosition": 1, ...}}を返します。 配列のみを取り出すには--results-onlyを使用します。getは{"Invoice": {...}}を返します。jq で内部の値を取得します:qbo get invoice 123 --json | jq '.Invoice'create/update/voidはgetと同じラッパーを返します。reportは{"Header": {...}, "Rows": {...}}を返します。
出力をプログラムで解析する場合は、必ず --json を使用してください。
よくあるパターン
# List with filtering — --results-only gives you the array directly
qbo list customers --sandbox --json --results-only
qbo list invoices --where "Balance > '0'" --sandbox --json --results-only
# Get by ID — drill into entity key with jq
qbo get invoice 145 --sandbox --json | jq '.Invoice'
qbo get customer 58 --sandbox --json | jq '.Customer | {Id, DisplayName, Balance}'
# Create from stdin
echo '{"DisplayName":"Acme Corp"}' | qbo create customer -f - --sandbox --json
# Create from file
qbo create invoice -f invoice.json --sandbox --json
# Record a payment against an invoice
echo '{"CustomerRef":{"value":"58"},"TotalAmt":500,"Line":[{"Amount":500,"LinkedTxn":[{"TxnId":"145","TxnType":"Invoice"}]}]}' | qbo create payment -f - --sandbox --json
# Sparse update (partial)
echo '{"Id":"58","SyncToken":"0","DisplayName":"New Name"}' | qbo update customer 58 --sparse -f - --sandbox --json
# Reports
qbo report profit-and-loss --start-date 2026-01-01 --end-date 2026-12-31 --sandbox --json
qbo report balance-sheet --sandbox --json
# Raw query
qbo query "SELECT Id, DisplayName, Balance FROM Customer WHERE Active = true" --sandbox --json --results-only
ワークフロー:作成 -> 請求書 -> 入金
# 1. Create customer
echo '{"DisplayName":"New Client","PrimaryEmailAddr":{"Address":"[email protected]"}}' \
| qbo create customer -f - --sandbox --json | jq '.Customer.Id'
# 2. Create item (service)
echo '{"Name":"Consulting","Type":"Service","IncomeAccountRef":{"value":"1"},"UnitPrice":150}' \
| qbo create item -f - --sandbox --json | jq '.Item.Id'
# 3. Create invoice (use IDs from above)
echo '{"CustomerRef":{"value":"CUSTOMER_ID"},"Line":[{"Amount":1500,"DetailType":"SalesItemLineDetail","SalesItemLineDetail":{"ItemRef":{"value":"ITEM_ID"},"Qty":10,"UnitPrice":150}}]}' \
| qbo create invoice -f - --sandbox --json | jq '.Invoice | {Id, DocNumber, TotalAmt}'
# 4. Record payment
echo '{"CustomerRef":{"value":"CUSTOMER_ID"},"TotalAmt":1500,"Line":[{"Amount":1500,"LinkedTxn":[{"TxnId":"INVOICE_ID","TxnType":"Invoice"}]}]}' \
| qbo create payment -f - --sandbox --json
添付ファイル
qbo attach invoice 123 receipt.pdf --json
qbo list attachable --where "AttachableRef.EntityRef.value = '123'" --json --results-only
qbo download <id>
取引 PDF
qbo pdf invoice 123 -o invoice-123.pdf # also estimate, salesreceipt, creditmemo, purchaseorder
取引の無効化
Invoice、Payment、SalesReceipt、または BillPayment を無効化すると、書類番号、日付、監査証跡を保持したまま金額がゼロになります。無効化は取り消せません。
qbo void invoice 145 --dry-run
qbo void invoice 145 --force --no-input --sandbox --json
qbo void payment 200 --sync-token 3 --force --no-input --sandbox --json
このコマンドは、送信前に現在の SyncToken を読み込みます。--sync-token を指定すると、期待する値を固定し、不一致の場合は送信せずに失敗します。すでに無効化されているレコード(TotalAmt がゼロで、PrivateNote が Voided で始まる場合)は、ヒントとともに返され、POST は行われません。ドライランでは API 呼び出しは行われません。トークンを固定した場合は、正確な本文が含まれます。--no-input とともに --force を使用してください。そうでない場合、コマンドは確認を求めます。
定期取引
スケジュールに従って取引を自動投稿するテンプレートです(例:月次の償却)。
各レコードは、型ごとの基礎となる取引を、ネストされた RecurringInfo
ブロックでラップします:{"JournalEntry": {"RecurringInfo": {...}, "Line": [...]}}。
qbo list recurringtransaction --json --results-only
qbo get recurringtransaction <id> --json
qbo create recurringtransaction -f examples/recurring-je.json --json
qbo delete recurringtransaction <id> # reads + echoes the full object for you
エージェントのイントロスペクション
qbo schema --json # Full CLI tree, all entities, all flags
qbo schema get --json # Schema for a specific command
qbo schema void --json # Void arguments and --sync-token flag
qbo exit-codes --json # Exit codes as JSON
終了コード
0=成功、1=エラー、2=使用方法、3=空、4=認証が必要、5=見つかりません、6=アクセス禁止、7=レート制限、8=再試行可能、10=設定エラー。
リファレンス
コマンドの全リファレンスについては、references/COMMANDS.md を参照してください。