Faelo / IRS Internal Revenue Manual API
IRS Internal Revenue Manual API
The internal procedures IRS staff follow for examinations, collection, appeals, penalties, and disclosure.
The Internal Revenue Manual is the IRS's internal how-to: what an examiner must do, when supervisory approval of a penalty is required, how a case moves to Appeals. It is distinct from the Internal Revenue Bulletin, which publishes new guidance. The IRS serves the IRM as a 26-part HTML navigation tree with no per-section search API.
Coverage
1,774 sections across 26 published parts. Source: Internal Revenue Service — public-domain US government work.
Routes
| Method | Path | Access | Price |
|---|---|---|---|
GET | /search?q=<keywords>&limit=<1-50> | free | — |
GET | /part/{number} | free | — |
GET | /section/{id} | free | — |
GET | /section/{id}/full | paid | $0.01 |
Live API root: https://irm-api.canvas-cart.workers.dev · /llms.txt · /stats
Record ids
a dotted section locator, e.g. "20.1.1" or "4.10.1"; get it from /search or /part/{number}.
Free search: https://irm-api.canvas-cart.workers.dev/search?q=supervisory+approval+penalty&limit=3
How an agent pays
Request /section/{id}/full. The API answers 402 Payment Required with the price ($0.01 per section), the network (eip155:8453), the USDC asset (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913), and the payout address. Pay, repeat the request, receive the full record. The 402 also carries x402 Bazaar discovery data.
import { wrapFetchWithPayment, x402HTTPClient } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(process.env.PRIVATE_KEY); // a funded Base wallet
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const httpClient = new x402HTTPClient(client);
const res = await fetchWithPayment("https://irm-api.canvas-cart.workers.dev/section/20.1.1/full");
const out = await httpClient.processResponse(res);
console.log(out.paymentStatus, out.body);