Guide
An insider trading API for your own filing alerts
The Filing Ahoy API gives a Pro account its own Form 4, Schedule 13D and 13G, and 8-K alerts as JSON. You can pull them from GET /api/v1/alerts with a cursor, have us POST each one to a webhook you control, or let your own AI client read them over MCP. The Pro plan, at $39.99 a month, covers all three. The pull API and MCP use your API key, and the webhook is signed with its own secret. Every alert is the one our email would send for the stocks and insiders on your watchlist.
What the API covers and what it leaves out
An alert is recorded for your account when we store a new filing for a company on your watchlist, or a filing that names an insider you follow. That is the same match our real time email uses, but the API does not depend on the email switch, so you can turn alert emails off and still get every alert through the API and the webhook. Alerts start from the moment the account is on Pro and watching the stock or following the insider. Filings from before that are not filled in afterward.
The API is read only. It answers GET (and HEAD) and nothing else, so adding or removing stocks and insiders still happens on the watchlist page. Answers are JSON only, no cookie is read or set, and no CORS header is sent, which means a web page on another site cannot read an answer in a visitor's browser. Call it from a script, a server or a scheduled job.
We keep API alerts for 30 days, then a daily job deletes them along with old webhook delivery records. Deleting your account deletes your keys, your API alerts, your webhook and its deliveries with it. The alerts are summaries of public SEC filings with a link to each one. They are not investment advice, and Filing Ahoy is not affiliated with the SEC.
Making and revoking a key
Keys are made in the API key section of your watchlist page with the Make a new key button. The key appears once, on the page that answers the button, and we keep only a SHA-256 hash of it and its last 4 characters. If you lose it, revoke it and make another. A key is fa_live_ followed by 52 lowercase letters and digits, 60 characters in all.
You can have 2 working keys at a time, so a script can move to a new key before you revoke the old one. Each key is listed by its last 4 characters with the date it was made and the date it was last used, which helps you spot a key that is in use somewhere you did not expect. The Revoke button next to a key stops it on the next request.
Send the key in the Authorization header as Bearer followed by a space and the key. If you move off Pro, the key stops working and each request gets a 403, but the key is kept and works again when the account is back on Pro.
Pulling alerts with GET /api/v1/alerts
GET https://filingahoy.com/api/v1/alerts answers with four fields. alerts is a list of your alerts, oldest first. next_cursor is the alert_id to send back as after on your next call. has_more is true when more alerts are waiting past this page. notice carries our not investment advice line.
The two query parameters are after and limit. Leave after out on the first call to start at the oldest alert we still keep, then pass next_cursor each time. limit is a whole number from 1 to 100, and 100 is both the default and the maximum. When nothing new has arrived, next_cursor comes back unchanged, so a script that polls on a schedule can store the cursor and ask again later. A malformed after or limit gets a 400 with a sentence saying what to fix.
alert_id values only grow and are never reused, even after old alerts are deleted. That makes them safe to use as a cursor and as the key for dropping a repeat you have already processed.
What one alert contains
Every alert has the same shape in the pull API, the webhook and the MCP tool. alert_id is a string. accession is the SEC accession number. form is the name of the filing, sent as one of these exact strings, "Form 4", "Form 4/A", "Schedule 13D", "Schedule 13D/A", "Schedule 13G", "Schedule 13G/A", "Form 8-K", "Form 8-K/A", or "SEC filing" for any other kind. title and summary are the subject line and summary our alert email uses. sec_url is the filing's index page on sec.gov, and accepted_at is EDGAR's acceptance time in UTC.
issuer holds the company name and its 10 digit CIK, and ticker is the ticker or null. When you watch the company, the name and ticker are the ones on your watchlist entry, as in the email. Otherwise they come from the filing and the SEC's ticker list. filers lists each reporting person with name, cik and role, where cik and role can be null. role is the reporting owner's relationship to the company on a Form 4, and null on the other forms.
Three fields depend on the form. transactions is filled for Form 4 only, one entry for every line of Tables I and II, each with table (nonDerivative or derivative), code (the transaction code such as P or S), security, date, shares, price and acquired_disposed (A or D). stake is filled for Schedules 13D and 13G only, with percent_of_class and shares for the lead reporting person, and is null otherwise. items is filled for Form 8-K only, with the item number and its label, such as 5.02. Share counts and prices stay the decimal strings the filer wrote, so nothing is rounded on the way to you.
Watchlist and insiders
GET /api/v1/watchlist answers with stocks, a list where each entry has ticker, cik, company_name and paused. GET /api/v1/insiders answers with insiders, a list where each entry has cik, name and paused. paused marks an entry past a lower plan's limit, which gets no alerts. Pro has no limit on stocks or insiders and the API answers only Pro keys, so every entry it returns has paused set to false.
Limits and error answers
A request with no key, a malformed key or a key we do not know gets a 401. A revoked key, or a key on an account that is not on Pro right now, gets a 403. More than 60 requests in a minute for one key, or more than 20 failed tries in a minute from one client address, gets a 429 with a Retry-After header giving the seconds to wait. Every error is JSON with one field, error, holding a plain sentence.
Both limits are counted in memory on each server instance, and each instance counts on its own. Treat 60 a minute per key as the pace to stay under. A problem on our side gets a 500 with a sentence asking you to try again in a minute.
The signed webhook
In the same section of the watchlist page you can save one HTTPS address. Saving it makes a new signing secret, 64 hexadecimal characters, shown once. Saving an address again replaces both the address and the secret. We refuse addresses that are not https, IP addresses, addresses with a user name or password, localhost and names ending in .localhost, .local or .internal, and single word host names. Redirects are not followed.
Each alert is POSTed as a JSON body with two fields, type set to alert and alert holding the object described above. The request carries Content-Type application/json, User-Agent FilingAhoy-Webhook/1, X-FilingAhoy-Timestamp with the time in unix seconds, and X-FilingAhoy-Signature with the signature.
A job that runs every minute sends the deliveries that are due, up to 20 a run and 5 at a time, each with a 10 second timeout. Any 2xx answer counts as delivered. Anything else, a timeout or a network error is retried after 1, 5, 30 and 120 minutes, and after the fifth attempt that delivery is marked failed. After 20 failed attempts in a row the webhook pauses and we send you one email about it. Alerts that arrive while the webhook is paused are still queued, and they are delivered after you press Resume on the watchlist page, as long as they are within the 30 days we keep alerts. Alert emails never depend on the webhook.
Delivery is at least once, so the same alert can arrive twice, for example when a run stops partway through a POST. Keep the alert_id values you have handled and skip any you see again. We also check the plan before each delivery, and an account that is no longer on Pro gets nothing sent.
Checking the webhook signature
The signature is the lowercase hexadecimal HMAC-SHA256 of the timestamp header, a period, and the raw request body, keyed with the signing secret's text exactly as it was shown to you. A match tells you the request came from someone holding that secret and that the body was not changed on the way.
To check one, read the body as raw text before any JSON parsing, because reformatting it changes the bytes. Join the X-FilingAhoy-Timestamp value, a period and that raw body into one string, compute HMAC-SHA256 over it with your secret, and write the result as lowercase hex. Compare it with X-FilingAhoy-Signature using a constant time comparison, such as timingSafeEqual in Node's crypto module, and refuse the request if they differ. Also refuse a timestamp that is far from your clock, for example more than 5 minutes off, so an old captured request cannot be replayed.
MCP with your key
Our MCP server at https://filingahoy.com/mcp speaks the Streamable HTTP transport from the Model Context Protocol specification. With no Authorization header it offers three public tools on SEC data, recent_filings, filing_facts and explain_form4_codes, and needs no account.
Send your Pro key as a Bearer token in the Authorization header and the same server also offers my_alerts, which takes after and limit and answers with the same fields as GET /api/v1/alerts, and my_watchlist, which lists your stocks and insiders. Your AI client calls the tools and pays for its own model use. If you send an Authorization header with a malformed, unknown or revoked key, or a key on an account that is not on Pro, the server answers with an error, so a typo in the key shows up right away.
The MCP server has its own limit of 60 requests a minute per client, checked before the key limits above. We tested the public tools with the official MCP TypeScript SDK client. Whether another AI app can send an Authorization header to a remote MCP server depends on that app, so check its settings before you count on the key tools there.
If you would rather go to EDGAR yourself
The SEC runs free EDGAR APIs at data.sec.gov that need no key, with each filer's submission history and XBRL financial data as JSON. To get from there to alerts like ours you would fetch the filings, read the Form 4 tables or Schedule 13D cover pages yourself, and match them to your list.
The SEC's webmaster FAQ asks automated tools to stay at or under 10 requests a second and to say who they are in a User-Agent header.
Not financial or investment advice. Filing Ahoy reports what was filed; it does not tell you what to buy or sell. Filing Ahoy is not affiliated with the SEC.
Sources
- U.S. Securities and Exchange Commission, EDGAR Application Programming Interfaces (APIs). Checked Oct 31, 2026.
- U.S. Securities and Exchange Commission, Webmaster Frequently Asked Questions. Checked Oct 31, 2026.
- Model Context Protocol, Transports, published Jun 18, 2025. Checked Oct 31, 2026.
Drafted with AI help. A person checked every fact and link on Oct 31, 2026.