Published fees for U.S. banks and credit unions, from national and district medians down to one institution, with call-report fee revenue and branch locations. Use it in your own code, in Excel, or by asking Claude. 50 fee categories.
Getting access
Subscribe to Hamilton on the $3,000 and $5,000 plans. Consultants pay the $3,000 a year price, so their plan includes it too. See Hamilton plans
Make your key on your account page. Everyone on the plan, up to 5 people, makes their own key. It shows once, with a Claude connector link, and you can replace it or turn it off there.
Call any endpoint below, or add the connector to Claude and ask in plain English. Your team shares 10,000 calls a month.
Example responses on this page show the real field names and shapes with illustrative numbers. For today's figures, see the Fee Index. Data refreshed Nov 12, 2026.
Base URL
https://feeinsight.com/api/v1
Authentication
Every request needs an API key. Everyone on the $3,000 and $5,000 plans makes their own on the account page. Pass yours in the Authorization header as a Bearer token, or as an api_key query parameter.
The Bash header example reads your key from the private credential file described in the local connection steps below. Replace the example path with its absolute path. --include shows the HTTP status and response headers alongside the JSON body.
In Windows PowerShell 5.1, curl is an alias for a different command; PowerShell 7 has no built-in curl alias. This single-line example uses native curl.exe and works in either version. Create the credential file described below, then replace the example path with its absolute path. The key stays in that file.
A key keeps working while your subscription is active, and for 7 days after a failed payment while the card is retried. It stops when the subscription ends. Keep it private. Anyone who has it can use your monthly calls and read the saved Hamilton institution and peer groups available to that key. Use your own personal key for saved context; keep it out of shared files and logs.
Claude connector
Add the connector once and ask Claude in plain English, for example which banks in Ohio have the highest overdraft fee, or how banks and credit unions in Texas compare. To add it, open Settings in Claude, then Connectors, add a custom connector and use this link with your key only for a private, per-user connection. Treat the full link as a credential; keep it out of terminals, shared configuration and logs. For a company connection, ask your administrator how each user supplies their own key. A shared URL key gives everyone that key's Hamilton context.
Each question Claude answers uses a few calls from your team's 10,000-a-month allowance.
Claude Desktop local connection
If your organization permits local MCP servers, Claude Desktop can connect through mcp-remote, an open-source bridge. Managed accounts may disable both custom connectors and local MCP; ask your owner or administrator for an approved connection method. This setup needs Node.js 22.12 or newer (check node -v and npx -v in a terminal). For Mac/Linux Desktop and the curl tests, create a plain-text headers.txt in a private folder on your computer, outside any repository or shared/synced folder. Put the following line in it, replacing the placeholder in your text editor. On Mac or Linux restrict access with chmod 600 /absolute/path/headers.txt; on Windows restrict the file to your user in Properties, then Security.
Credential file contents
Authorization: Bearer YOUR_API_KEY
Replace the example username and path below with the absolute path to your credential file. On Linux use your home path, such as /home/YOUR_USERNAME/.feeinsight/headers.txt. In Claude Desktop, open Settings, then Developer, then Edit Config, and add this entry to claude_desktop_config.json. If the file already has mcpServers, add only the bank-fee-index entry inside it. Save, quit Claude Desktop fully and reopen it.
Windows Desktop uses the bridge's environment-reference form to avoid cmd/npx quoting problems with paths or header values containing spaces. In the private config below, replace only inside ; leave the argument reference unchanged. Restrict this config to your user, keep it out of shared files and repositories, and never post its contents. After saving, quit Claude Desktop from the system tray and reopen it.
Rate Limits
Each plan gets one monthly allowance, shared by every key on it and across all endpoints. When it runs out, calls return 429 rate_limited until the allowance resets on the 1st of the next month (UTC). Each plan can also make up to 60 calls a minute, and calls past that return 429 burst_limited with a Retry-After header giving the seconds to wait. Unlimited keys get no X-RateLimit-Limit or X-RateLimit-Remaining headers.
Data responses carry an ETag; send it back in If-None-Match to get 304 Not Modified when nothing changed (a 304 still counts as a call). /hamilton-context and personalized /peers responses are private, use no-store and do not return an ETag or 304.
X-RateLimit-Limitheader-- Maximum requests in the current window
X-RateLimit-Remainingheader-- Requests remaining
X-RateLimit-Resetheader-- ISO 8601 UTC time when the monthly window resets
Retry-Afterheader-- On 429 burst_limited, seconds to wait
API monthly request allowance
Tier
Monthly limit
How to get it
Hamilton key
10,000 requests
Account page, $3,000 and $5,000 plans
A Hamilton key reads fees one institution at a time, for up to 250 different institutions a month; institutions you have already read that month stay available. Fee rankings are national and list the first 50 institutions. Fee rows across every institution need an Enterprise key.
Errors and recovery
Errors return JSON with a readable error message and a stable code. Check the HTTP status and code before retrying. Error responses are never cached.
Example error · HTTP 400
{
"error": "state must be a two-letter code such as TX",
"code": "invalid_parameter"
}
API error statuses, codes and recovery actions
HTTP status
Code
What to do
403
account_context_required
Use your own Hamilton subscriber key for saved account context. Generic partner keys have no personal mapping; pass explicit institution and peer parameters instead.
401
api_key_required
Send your API key in the Authorization header, or make a key on your account page.
429
burst_limited
Wait the number of seconds in Retry-After before retrying; spread requests out across the minute.
503
context_unavailable
Saved Hamilton context could not be read. Retry later; no partial account context is returned.
503
data_unavailable
Revenue data is temporarily unavailable. Retry later; contact us if it persists.
403
enterprise_required
Fee rows across every institution need an Enterprise key. Pass institution_id to read one institution, or contact us about an Enterprise key.
Returns the fee index for every category. Filter by state, charter type, Federal Reserve district or asset size to benchmark a peer group. Includes maturity indicators and bank and credit union counts.
Parameters
GET /index parameters
Name
Type
Description
state
string
Two-letter state code (e.g., CA, TX)
charter
string
"bank" or "credit_union"
district
string
Fed district number(s), comma-separated (e.g., 7 or 2,7,12)
Paginated list of banks and credit unions. Filter by state, charter, size or city, search by name, or rank by one fee. Each row has fee count, total assets (in thousands of dollars) and Fed district.
Parameters
GET /institutions parameters
Name
Type
Description
state
string
Two-letter state code
charter
string
"bank" or "credit_union"
has_fees
boolean
"true" to return only institutions with published fees
q
string
Search by name, e.g. JPMorgan Chase
asset_tier
string
GET/institutions?view=feesHamilton · $3,000 and $5,000 plans
Published dollar fees as one row each, oldest first by publish date, then by fee_id. A Hamilton key must pass id and reads one institution's fees; rows across every institution need an Enterprise key. To keep your own copy current, save the newest published_at you hold and ask again with updated_since set to it. Rows published at exactly that time come back again, so match them on fee_id. A fee that is taken down drops out of the list and is not reported as a change, so pull the full list without updated_since from time to time to catch removals.
Parameters
GET /institutions?view=fees parameters
Name
Type
Description
viewrequired
string
"fees"
updated_since
string
An ISO 8601 date or time, such as 2026-10-01 or 2026-10-01T00:00:00Z. Only fees published on or after it are returned.
id
integer
Hamilton Context
GET/hamilton-contextHamilton · $3,000 and $5,000 plans
Returns the subscriber key holder's saved Hamilton institution and authorized personal or workspace peer sets. If no saved institution is available, the current account institution may supply it. Requires your own subscriber key or a paid signed-in session; generic partner keys return 403 account_context_required. Responses are private and never cached. It returns institution and peer context without account identifiers, contact details or billing information.
For each fee the institution publishes in dollars, shows its amount next to the peer median and the 25th and 75th percentiles. Your own subscriber key can supply omitted institution and peer defaults from Hamilton. Explicit peer_ids or peer-group parameters bypass saved peer defaults. Choose one authorized saved_peer_set_id, explicit peer_ids, or peer-group parameters; do not combine a saved set with explicit peers or filters. use_saved_context=false disables automatic defaults while still allowing an explicit authorized saved set. Without saved peers, the default group uses the institution's charter type, asset size and Fed district. Only the peer-group parameters you set apply, and "same" means the institution's own value. The percentile counts peers with lower amounts plus half of ties. When fewer than 5 peers publish a fee, the median and percentiles are left out. Fees stated as a percentage are listed separately and not compared.
Parameters
GET /peers parameters
Name
Type
Description
institution_id
integer
Institution ID; optional when saved Hamilton or current account context supplies it. If neither is available, the request returns 400 invalid_parameter
saved_peer_set_id
integer
One authorized saved personal or workspace peer set. Cannot combine with peer_ids or peer-group parameters. Missing or unauthorized sets return 404 not_found; generic partner keys return 403 account_context_required
Some fees are a percentage rather than a flat amount, such as a foreign transaction fee charged as a share of the purchase. This endpoint lists them with the rate, any dollar minimum or maximum the schedule states, and the link to the schedule. They are kept apart from dollar fees and never included in dollar medians. A Hamilton key must pass institution_id; rows across every institution need an Enterprise key.
Parameters
GET /rate-fees parameters
Name
Type
Description
institution_id
integer
One institution's rate fees (required unless you hold an Enterprise key)
Call-report fee income in thousands of dollars per quarter, newest first. FDIC reports banks' service charges on deposit accounts. NCUA reports credit unions' broader fee income. The two measure different things. By default each row keeps its original fields, but service_charges, institutions, bank_service_charges and credit_union_service_charges are deprecated because they mix the two regulators. Read by_regulator instead, which gives each regulator's own figure. Ask for source=fdic or source=ncua to get only that regulator's rows. The districts view gives one row per Fed district per quarter.
Parameters
GET /revenue parameters
Name
Type
Description
view
string
"national" (default) or "districts"
quarters
integer
Quarters to return, back to 2010 (default: 8, max: 66)
source
string
"fdic" (banks) or "ncua" (credit unions): only that regulator's rows, each naming its source and measure
Bank branches come from the FDIC Summary of Deposits, with deposits. Credit union branches come from NCUA, without deposits. Each has an address and, where known, latitude and longitude. Pass institution_id for one institution, or state (optionally with city or zip) for an area.
Parameters
GET /branches parameters
Name
Type
Description
institution_id
integer
One institution's branches
state
string
Two-letter state code
city
string
Exact city name, with state
zip
string
Five-digit ZIP code, with state
API Pricing
Hamilton
$3,000/yr and up
✓Your own API key, made on your account page
✓Claude connector
✓10,000 calls a month
✓All 50 fee categories
✓Institution-level fees, peer comparison, fee revenue and branches
Methodology. Medians, percentiles, and ranges are computed from non-rejected fee observations only.
Sources. Institution data is sourced from FDIC (banks) and NCUA (credit unions) registries. Fee data is read from published fee schedules; fees the software is not sure about are held for a person to check.
Status. Each category carries a status: Strong (20+ institutions with published fees), Provisional (5 to 19), or Too few to benchmark (under 5, no median shown).
Tier system. Categories are organized into 4 tiers: spotlight, core, extended, and comprehensive.
Coverage. The dataset covers 4,053 institutions with published fees (of 8,512 monitored) and is refreshed on a rolling calendar. Data refreshed Nov 12, 2026.
Machine-readable specification
Import our OpenAPI 3.0 spec into Postman, Swagger UI, or your code generator of choice.
For Claude Code, make FEEINSIGHT_API_KEY available through your environment or secret manager before starting Claude Code. Keep the variable reference below as written; do not replace it with the key. Add the entry to your project's .mcp.json(or merge it into an existing mcpServers object), approve the project connection, then use /mcp in a session to check it. This config contains no key value.
Replacing or turning off a key stops the old one at once. Update the local credential file, Claude Code environment, or remote connector connection you configured, then restart the connection.
Claude Desktop ignores a config file that is not valid JSON. Check that every brace and comma is in place, especially between two entries in mcpServers.
“Unexpected token ‘<’” means the client received non-JSON content. Check the endpoint URL, HTTP status and Content-Type for an HTML error, redirect or deployment protection page. API key refusals return JSON; this parse error alone does not identify a bad key.
To test the key on its own, use the Bash header example or the single-line PowerShell example above. Read the HTTP status and JSON code and error message. api_key_required means no accepted key was supplied; invalid_api_keycan mean an unknown key or an unavailable account. For key_revoked, replace the key; for subscription_inactive or seat_removed, restore the plan or seat access. The error table below lists the recovery steps.
Your own subscriber key can use the institution and peer sets you saved in Hamilton. Ask Claude to call get_hamilton_context first, or call /hamilton-context from your code. Peer comparison uses those defaults when you omit explicit values. A generic partner key has no personal account mapping.
What Claude can look up
get_hamilton_contextYour Hamilton context
get_fee_indexTypical fees
list_fee_categoriesFee categories
get_fee_categoryOne fee nationally
find_institutionsFind banks
get_institutionOne bank in full
rank_institutions_by_feeWho charges the most
get_revenue_trendFee revenue over time
get_fee_changesRecent fee changes
get_branchesBranch locations
get_local_marketLocal competitors
get_peer_comparisonFees against peers
get_rate_feesFees stated as a rate
429
institution_limit
Your team has read fees for 250 different institutions this month. Institutions already read stay available; the count resets on the 1st (UTC). Contact us about an Enterprise key.
401
invalid_api_key
Check that you copied the whole key. A subscriber key also requires active payer and holder accounts; contact us if account access is unavailable.
400
invalid_parameter
Read the error message, correct the named query parameter and retry.
401
key_revoked
Make a replacement key on your account page, or contact us about a partner key.
404
not_found
Check the category or institution ID. A local market may not be on file for that institution.
403
plan_required
Use a key covered by the $3,000 and $5,000 plans, or an eligible partner key. The response includes upgrade_url.
429
rate_limited
Your team used its monthly allowance. Wait until the reset time in reset or X-RateLimit-Reset (the 1st of next month, UTC).
503
rate_limit_unavailable
Usage tracking is temporarily unavailable. Wait the Retry-After seconds (60) and retry.
401
seat_removed
Ask the plan owner to add you back to their workspace.
401
subscription_inactive
Restart the Hamilton subscription that covers this key from your account page.
by_charter_type[]array-- Bank and Credit Union breakdowns, labeled by dimension_value
by_asset_tier[]array-- Breakdowns by asset size tier, labeled by dimension_value
by_fed_district[]array-- District breakdowns, labeled District 1 through District 12
by_state[]array-- Up to 15 state breakdowns, labeled by two-letter state code
by_charter_type[].median_amountnumber | null-- Median in USD; each breakdown also includes count, min_amount, max_amount, avg_amount, p25_amount and p75_amount
Example response · illustrative values, not live data
data[].bank_countinteger-- Number of banks in sample
data[].cu_countinteger-- Number of credit unions in sample
data[].unstated_audience_institution_countinteger-- Institutions in the sample with at least one fee whose schedule doesn't say whether it's personal or business; those fees count as personal. It counts every institution, while institution_count counts institutions that share one fee schedule once, so the two are not a ratio.
Example response · illustrative values, not live data
Asset-size tier(s), comma-separated, e.g. community_small, community_mid
city
string
Exact city name, e.g. Austin (not with q or fee_category)
fee_category
string
Rank by one fee, e.g. overdraft (Hamilton keys). Each row gains fee_amount, the institution's lowest published amount for that fee. A Hamilton key gets a national ranking (no state, charter or q) of the first 50 institutions.
sort
string
"highest" (default) or "lowest", with fee_category
One institution's profile with its published fees and source links, call report figures and complaint counts. Add view=benchmark for its fees beside peer medians (format=csv for a spreadsheet) or view=regulatory_watch for local competitor enforcement records, fee comparisons and tracked rule changes. Where it charges several different fees in one category, amount is null and each fee is listed by name (in view=regulatory_watch, with the lowest and highest amounts).
Parameters
GET /institutions?id={id} parameters
Name
Type
Description
idrequired
integer
Institution ID
view
string
"detail" (default), "benchmark" or "regulatory_watch"
quarters
integer
Call report quarters, newest first (default: 8, max: 66)
format
string
"csv" with view=benchmark
updated_since
string
An ISO 8601 date or time, such as 2026-10-01 or 2026-10-01T00:00:00Z. Only fees published on or after it are returned.
fees[]array-- Every published fee for this institution
fees[].source_urlstring-- The fee schedule the fee was read from
call_reports[]array-- FDIC or NCUA call report figures by quarter, in whole dollars
complaints[]array-- CFPB complaint counts by product, when any are on file
fees[].fee_namestring-- The fee's name as the bank's schedule words it, made complete where the row leaves its heading out ("3 X 10" shows as "Safe Deposit Box 3 X 10"). When that name was cut off mid-line, the fee category's name stands in.
fees[].name_is_category_fallbackboolean-- true when fee_name is the category's name standing in for a cut-off name; false when it is the schedule's own name, or that name made complete
Default true. false disables automatic institution and peer defaults; an explicitly requested authorized saved_peer_set_id still works. Saved-context comparisons are private and never cached
peer_ids
string
Up to 25 institution IDs, comma-separated, to use as the peer group. Not combined with the parameters below
charter
string
bank, credit_union or same, e.g. bank
asset_tier
string
Asset-size tiers, comma-separated, or same, e.g. community_mid,community_large
asset_min
string
Minimum total assets, in whole dollars, e.g. 500000000
asset_max
string
Maximum total assets, in whole dollars, e.g. 2000000000
state
string
Two-letter state codes, comma-separated, or same, e.g. TX,OK
district
string
Fed districts 1-12, comma-separated, or same, e.g. 11
regulator
string
occ, fdic, fed or ncua, comma-separated, or same, e.g. occ,fed
cu_charter
string
Credit unions only: federal, state or same, e.g. federal
holding_company
string
Holding company RSSD id, or same for the institution's own, e.g. same
market
string
Metro (MSA) code, or same for the metro holding most of the institution's branches. Peers are institutions with a branch there., e.g. same
nearest
string
The N institutions closest in total assets (1-100) among those meeting the other parameters and publishing fees, e.g. 20
Try it
# Use your saved Hamilton institution and active peer set
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://feeinsight.com/api/v1/peers"
# Choose an authorized saved peer set for one institution
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://feeinsight.com/api/v1/peers?institution_id=323&saved_peer_set_id=31"
# Use only the explicit institution and the default charter/size/district group
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://feeinsight.com/api/v1/peers?institution_id=323&use_saved_context=false"
# Banks with branches in the same metro, $1B to $10B in assets
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://feeinsight.com/api/v1/peers?institution_id=323&charter=bank&market=same&asset_min=1000000000&asset_max=10000000000"
Response fields
contextobject-- institution_source, peer_source, saved_peer_set_id and saved_peer_set_name explain the applied defaults
peer_group.labelstring-- Which institutions were compared
categories[].amountnumber-- The institution's amount in USD; null when it charges several different fees in the category
categories[].feesarray-- Each of the institution's fees as name and amount, lowest first; amount_low and amount_high on the category give the range
categories[].peer_mediannumber-- Median among peers that publish the fee
categories[].peer_countinteger-- Peers that publish the fee
categories[].percentileinteger-- 0 to 100, the share of peers with a lower amount
rate_fees[]array-- Fees stated as a percentage, listed apart
Example response · illustrative values, not live data
{
"institution": { "id": 323, "name": "Capital City Bank", "state": "FL", "charter_type": "bank", "asset_tier": "community_large", "fed_district": 6 },
"peer_group": {
"basis": "default",
"label": "Banks with $1B to $10B in assets in the Atlanta Fed district",
"peers_with_fees": 38
},
"min_peers": 5,
"categories": [
{
"category": "overdraft",
"display_name": "Overdraft (OD)",
"amount": 35.00,
"amount_low": 35.00,
"amount_high": 35.00,
"fees": [{ "name": "Overdraft Item Fee", "amount": 35.00 }],
"peer_count": 38,
"peer_median": 30.00,
"peer_p25": 27.00,
"peer_p75": 32.00,
"peers_lower": 30,
"peers_same": 3,
"peers_higher": 5,
"percentile": 83,
"maturity_tier": "strong"
}
],
"rate_fees": [],
"context": {
"institution_source": "explicit",
"peer_source": "default",
"saved_peer_set_id": null,
"saved_peer_set_name": null
},
"note": "Each row compares the institution's published dollar amount with the same fee at its peers.",
"attribution": {"text":"Source: Bank Fee Index, feeinsight.com","url":"https://feeinsight.com"}
}
string
"bank" or "credit_union"
updated_since
string
An ISO 8601 date or time, such as 2026-10-01 or 2026-10-01T00:00:00Z. Only fees published on or after it are returned.
Who competes in an institution's local market: the counties holding most of its deposits (for credit unions, its headquarters city's counties), with each competitor's deposits there and its deposit share. Credit unions have no deposit figure, so their share is null.