Reverse stock split calendar, history and source filings. Requires SplitScanner or Signal8 Pro.
Maintained by@fullstacktard(verified)Also a maintainer?
Call this server's tools from your browser. Nothing to install.
Optional. Bearer token using a Signal8 API key. Clients that support MCP OAuth can omit this and sign in. Tool calls require SplitScanner or Signal8 Pro.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Free: works without an API key or Pro plan (the hosted server only needs a signed-in account). Looks up a term in the Signal8 Academy glossary (signal8.ai/learn/glossary): dilution, SEC filing and trading jargon such as "ATM offering", "baby shelf", "full ratchet", "pre-funded warrant", "going concern", "LULD", "days to cover", "Form 25". Accepts a glossary slug ("atm-offering"), the term itself, or a common alias ("ATM", "price reset"); matching is case- and punctuation-insensitive. Returns the term, a one-line short definition, the long definition as Markdown, related terms, the Academy guides that use it, and the public url. A TERM_NOT_FOUND error means the glossary has no entry for that wording, not that the concept does not exist; the Academy guide search may still cover it.
Term, alias or glossary slug, e.g. "baby shelf", "ATM", "full-ratchet".
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http mcp https://mcp.splitscanner.com/mcp
Headers
Authorization (optional, not in the config above): Optional. Bearer token using a Signal8 API key. Clients that support MCP OAuth can omit this and sign in. Tool calls require SplitScanner or Signal8 Pro.Free: works without an API key or Pro plan (the hosted server only needs a signed-in account). Looks up a term in the Signal8 Academy glossary (signal8.ai/learn/glossary): dilution, SEC filing and trading jargon such as "ATM offering", "baby shelf", "full ratchet", "pre-funded warrant", "going concern", "LULD", "days to cover", "Form 25". Accepts a glossary slug ("atm-offering"), the term itself, or a common alias ("ATM", "price reset"); matching is case- and punctuation-insensitive. Returns the term, a one-line short definition, the long definition as Markdown, related terms, the Academy guides that use it, and the public url. A TERM_NOT_FOUND error means the glossary has no entry for that wording, not that the concept does not exist; the Academy guide search may still cover it.
| Argument | Type | Description |
|---|---|---|
| term* | string | Term, alias or glossary slug, e.g. "baby shelf", "ATM", "full-ratchet". |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"term"
],
"properties": {
"term": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Term, alias or glossary slug, e.g. \"baby shelf\", \"ATM\", \"full-ratchet\"."
}
},
"additionalProperties": false
}Get an enriched company profile by ticker symbol. Returns CIK, exchange, sector, industry, market cap, employee count, description, and other fundamental data in a lightweight response. Includes halted/haltCode/haltedAt trading-halt status on every call (false/null when trading normally); a halted-but-listed ticker reports delisted:false. `sharesOutstanding` is dated: `sharesOutstandingAsOf` + `sharesOutstandingAsOfKind` ("stated" = the issuer's statement date; "checked" = when it was last confirmed against a vendor; "none" = date not recorded) and a vendor-free `sharesOutstandingSource`. The count is only meaningful with its date. A null count means not measured; it does not mean zero. `cik: null` is a foreign issuer listed on US OTC that files nothing with the SEC (e.g. PGPHF): name, exchange and country come from reference data and every field Signal8 lacks is null.
| Argument | Type | Description |
|---|---|---|
| ticker* | string | Stock ticker symbol (e.g., AAPL, TSLA) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., AAPL, TSLA)"
}
},
"additionalProperties": false
}Get full compliance rules evaluation for a company: Nasdaq/NYSE deficiency detection, bid price tracking, and delinquent filing detection, combining SEC filing data, market data and exchange rules. Rules cover bid price, equity, reverse-split limit, market value of publicly held shares, publicly held shares, holders, timely periodic filings, annual meeting and audit committee, per exchange tier. Standards that could not be judged from any measurement are listed in `notEvaluated`: they are neither passing nor failing. Neither a `notEvaluated` standard nor the absence of a deficiency notice is evidence of compliance.
| Argument | Type | Description |
|---|---|---|
| ticker* | string | Stock ticker symbol (e.g., AAPL, TSLA) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., AAPL, TSLA)"
}
},
"additionalProperties": false
}Reverse-split episodes across companies that ended without the split taking effect, from Signal8's SEC-filing tracker: outcome "vote_failed" (shareholders did not approve), "abandoned" (the company said it will not proceed), "authority_expired" (an approval lapsed unused past its stated deadline) or "postponed_indefinitely". Splits that did happen are not in this list, and it is cross-company rather than one company's full history. Newest end first. Each row is the Reverse Splits page row (ticker, companyName, hasPage, ratio / ratioMin / ratioMax, trackerState, meetingDate, approvedDate, exchange, securityType, marketCapUsd, cik, approvalPath, domicile, splitAuthority, authorityTerms, verification) plus sourceUrl / sourceAccession and sourceDocuments (every document behind the episode, each with accession or URL) and an "ended" block: outcome, outcomeLabel, endedOn, endedOnBasis, closedReason (the tracker's own note, verbatim), voteDate, closingAccession / closingUrl (the filing that closed it, when one did). endedOnBasis says what endedOn is: "vote_date" or "meeting_date" = the vote as stated; "authority_expiry" = the stated last day of the authority; "closing_filing" = the ET day of the filing that closed it; "recorded" = none of those, the day the tracker recorded the close, which can be later than the event. Null means not measured or not stated. An empty list is what the tracker has on file for the window, not evidence that no company abandoned a split; completeness "tracked_episodes" = what the tracker has read from filings since it started, not every company. boundReached: true = the window held more episodes than one read returns (a narrower from / to window returns the rest). Locked rows are withheld, not absent. The facts are part of Signal8 Pro: a key not owned by a Pro account gets rows with locked: true and only ticker, companyName, hasPage and exchange (access "preview", lockedCount); a locked row means the facts were withheld from this caller. outcome, from and to are Pro-only filters: on a non-Pro key they apply to unlocked rows only and locked rows are left out (filtersLimitedToUnlocked: true). exchange applies to every row. Paging uses limit and the nextCursor of the previous response (null = last page). available: false (reason "tracker_not_enabled") = the tracker is switched off; an HTTP 503 FEATURE_DISABLED = the Reverse Splits page is switched off. In both cases the response says nothing about any company. The data describes what is on file and carries no view on the company, its price, or what anyone should do.
| Argument | Type | Description |
|---|---|---|
| to | string | Latest endedOn, YYYY-MM-DD (default: today, US Eastern). |
| from | string | Earliest endedOn, YYYY-MM-DD (default: 365 days before "to"). |
| limit | integer | Rows per page, 1 to 200 (default 50). |
| cursor | string | nextCursor from the previous page. Omit for the first page. |
| outcome | array | Outcomes to keep: vote_failed, abandoned, authority_expired, postponed_indefinitely. Empty = all four. |
| exchange | array | Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"to": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Latest endedOn, YYYY-MM-DD (default: today, US Eastern)."
},
"from": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Earliest endedOn, YYYY-MM-DD (default: 365 days before \"to\")."
},
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Rows per page, 1 to 200 (default 50)."
},
"cursor": {
"type": "string",
"maxLength": 16,
"description": "nextCursor from the previous page. Omit for the first page."
},
"outcome": {
"type": "array",
"items": {
"enum": [
"vote_failed",
"abandoned",
"authority_expired",
"postponed_indefinitely"
],
"type": "string"
},
"description": "Outcomes to keep: vote_failed, abandoned, authority_expired, postponed_indefinitely. Empty = all four."
},
"exchange": {
"type": "array",
"items": {
"enum": [
"NASDAQ",
"NYSE",
"AMEX",
"OTC",
"not_measured"
],
"type": "string"
},
"description": "Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row."
}
},
"additionalProperties": false
}Get the full text/HTML content of a single exhibit from an SEC filing, by exhibit id. Returns the exhibit text along with exhibit_type, description, company_name, accession_number, and form_type. maxLength truncates large exhibits. Exhibit ids appear as `exhibitId` in a filing's document list, as `id` in a filing's exhibit list, and as `exhibit_id` on full-text search matches.
| Argument | Type | Description |
|---|---|---|
| id* | string | Exhibit ID (numeric), as listed for the filing's exhibits. |
| maxLength | number | Truncate content to this many characters. Response includes a "truncated" boolean. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "Exhibit ID (numeric), as listed for the filing's exhibits."
},
"maxLength": {
"type": "number",
"minimum": 100,
"description": "Truncate content to this many characters. Response includes a \"truncated\" boolean."
}
},
"additionalProperties": false
}Get the full raw text/HTML content of an SEC filing by its internal filing ID (the `id` on filing search rows, or `filingId` from an accession-number lookup or a filing's document list). Returns the complete filing document, which can be very large (10-K filings can be 1MB+); maxLength truncates content for previews. The response includes company_name, form_type, filing_date, cik, and accession_number alongside the content. Record-only filings (bodyStored: false) have no body here; the document is on sec.gov. Content is the whole submission as filed. Coverage: Signal8's SEC EDGAR archive, updated through the day, in its held range (see `archiveFrom` in each response; currently from late 2021, expanding back to 2016 as the history backfill fills in). Before archiveFrom it holds only a scatter, so absence before archiveFrom is not evidence a filing was never filed; SEC EDGAR itself covers earlier periods. Record-only rows (bodyStored: false) have no stored body; the document is at its sec.gov URL.
| Argument | Type | Description |
|---|---|---|
| filingId* | string | Internal filing ID (numeric), the `id` on filing search rows. |
| maxLength | number | Truncate content to this many characters. Useful for previewing large filings. Response includes a "truncated" boolean when truncation is applied. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"filingId"
],
"properties": {
"filingId": {
"type": "string",
"description": "Internal filing ID (numeric), the `id` on filing search rows."
},
"maxLength": {
"type": "number",
"minimum": 100,
"description": "Truncate content to this many characters. Useful for previewing large filings. Response includes a \"truncated\" boolean when truncation is applied."
}
},
"additionalProperties": false
}List every document in one SEC filing by accession number (the primary document, each exhibit, XML and XBRL files, graphics) with seq, type (e.g. "8-K", "EX-99.1"), description, size in bytes, `stored` and `secUrl`. Also returns the filing's cik, companyName, formType, filingDate, acceptedAt, bodyStored, primaryDocument, indexUrl, and `filingId`. A document with an `exhibitId` has readable stored text under that exhibit id; `filingId` identifies the whole submission text. `exhibitId: null` means the document has no readable text row here (XML/XBRL/graphics, or text not held); its `secUrl` still opens it. When `readableIdsResolved` is false the id lookup failed and exhibitId is omitted (unknown, not "none"). `stored: false` means Signal8 holds the filing record but not that document's body; it exists on EDGAR at `secUrl`. A filing not held in the archive returns a not-found error; its documents are still on EDGAR. Coverage: Signal8's SEC EDGAR archive, updated through the day, in its held range (see `archiveFrom` in each response; currently from late 2021, expanding back to 2016 as the history backfill fills in). Before archiveFrom it holds only a scatter, so absence before archiveFrom is not evidence a filing was never filed; SEC EDGAR itself covers earlier periods. Record-only rows (bodyStored: false) have no stored body; the document is at its sec.gov URL.
| Argument | Type | Description |
|---|---|---|
| accessionNumber* | string | SEC accession number, dashed ("0001193125-22-010026") or 18-digit compact form |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"accessionNumber"
],
"properties": {
"accessionNumber": {
"type": "string",
"description": "SEC accession number, dashed (\"0001193125-22-010026\") or 18-digit compact form"
}
},
"additionalProperties": false
}List the readable exhibits (individual documents with stored text) within an SEC filing, by internal filing ID. Returns each exhibit's `id` (the exhibit id for reading that exhibit's text), exhibit type, description, content size and sec_url. Excludes XML/XBRL and documents with no stored text.
| Argument | Type | Description |
|---|---|---|
| filingId* | string | Internal filing ID (numeric), the `id` on filing search rows. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"filingId"
],
"properties": {
"filingId": {
"type": "string",
"description": "Internal filing ID (numeric), the `id` on filing search rows."
}
},
"additionalProperties": false
}Get float data for a company: floatShares, floatDefinition, the as-of date and, when the headline float is withheld, the bounds and labelled stand-ins that replace it. Null, absent or withheld means not measured; it does not mean "no float", "no restricted shares" or zero. A numeric 0 is a measured zero, so the reason and marker fields ("floatWithheldReason", "restrictedBlockCount", "provenance", "direction") carry the verdict, not the value alone. The share count the float was judged against ("basisSharesOutstanding") is dated by "sharesOutstandingAsOf" and "sharesOutstandingAsOfKind" ("stated", "checked", or "none" = date not recorded) and "sharesOutstandingSource". "floatDefinition": "tradeable" (shares outstanding minus affiliates minus restricted/unregistered blocks; filing-derived snapshot tickers), "non_affiliate" (the SEC I.B.6 figure, which includes restricted shares held by non-affiliates and is not a trader's float), "non_affiliate_estimate" (from ownership filings), "free_float" (vendor). "floatDefinition" and "source" appear only on snapshot results; an absent floatDefinition means the figure is not a filing-derived tradeable float. "nonAffiliateFloatShares" (snapshot tickers) is the input that baby-shelf / I.B.6 math rests on; it is not tradeable supply, and the tradeable float is not an I.B.6 input. Precedence: when the snapshot carries any figure ("floatEstimate", "tradeableFloatCeiling", an "affiliateBasis" range), "floatShares" stays null and that figure is the answer. A lower tier fills "floatShares" (its own "source" and definition, with "snapshotFloatWithheldReason" as provenance context, not a second refusal) only when the snapshot has no figure, or its only figure is a trivial ceiling (at or above 99% of the share count), which is stripped. Floors, points, every "shares_outstanding_ceiling" and an "affiliate_sizing_estimate" (with its "reason" and "unsizedAffiliates") are kept. A lower tier that also answered appears as "otherSourceFloat" {floatShares, source, provenance:"other_source", floatDefinition, asOfDate}: a secondary other-source figure, not the float and not an input to arithmetic. A lower-tier figure that predates a split the snapshot names, predates recorded issuances of 10% or more of it, or falls outside the snapshot's bounds is refused: "fallbackRefusal" {reason, refusedSource, detail}. "floatShares" null with "floatWithheldReason" set and no lower-tier figure means no source could answer. A point (bound "point", or a "floatEstimate" with "statedAsOf" {asOf, source, events[]}) is a plain number as of asOf, with the unsized later issuances in "statedAsOf.events" as its caveat. A ceiling, floor or range is not a float figure: it means the filings put the float at most or at least N. Stand-ins on a withheld result are not floats and are not inputs to a market cap, percent-of-float, short-interest ratio, screen, sort or comparison. (1) "tradeableFloatCeiling": the tradeable float is at most this (null = no bound, not 0). (2) "affiliateBasis.floatLowerBound" / "floatUpperBound": a range for the non-affiliate float (still including non-affiliate restricted shares); each end is null independently; on a published float it is context only. (3) "floatEstimate" {shares, basis, direction, confidence, rung, bound, asOf, reason, qualifier, offBasis, statedAsOf, staleness}: "basis" says what it rests on; "direction" "overstates" = the true float is at most shares, "understates" = at least, "unknown"; "rung" names the ladder step; rung "best_estimate" is the most likely figure when every filing rung withheld ("basisKind" = what it rests on, "assumptions" = how each unsized holder was treated), an estimate and not a measurement; "qualifier" is the caveat that belongs with the figure. "offBasis": "pre_split_as_filed" (as of asOf, before "splitsAfter" [{ratio, effectiveDate, status}]), "ordinary_shares_unconverted" (ordinary shares, not ADSs), "count_predates_issuances" (dated cover count "countSource", later issuances uncounted); an offBasis figure is accurate only with its label and is not comparable with a price, market cap, another float or a threshold. "staleness" flags a point older than 12 months or post-dated by a known issuance. An estimate never becomes floatShares. Unrelated to the boolean "floatEstimated" (a published floatShares back-derived from a USD public-float disclosure). (4) "vendorFallback" {floatShares, provenance:"vendor", floatDefinition:"free_float", asOfDate, splitAdjusted}: a third-party free float as of its date, not Signal8's float. "restrictedShares" null means not measured (a block exists whose size the filings leave unstated), not zero; "restrictedBlockCount" 0 is a measured answer. "affiliateBasisStale" (basisSpanDays, affiliateAnchorDate) labels an affiliate table materially older than the share count. "tradeableBasis": "convention_conservative" means a published convention resolved the figure (see "tradeableConvention"), so it is not exact.
| Argument | Type | Description |
|---|---|---|
| ticker* | string | Stock ticker symbol (e.g., "AAPL", "TSLA") |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., \"AAPL\", \"TSLA\")"
}
},
"additionalProperties": false
}Get the point-in-time float history for a company: one sample per trade date (float shares, shares outstanding, and the source the float came from), showing the float on a past date and how it expanded across a dilution event. The series is forward-only: it began accumulating in mid-2026 and is not backfilled, so early or absent history is expected and an empty rows array is a normal result, not an error or a sign of delisting. Each row carries "source" ("computed", "sec_10k" or a market-data vendor tier) because float quality varies by provider.
| Argument | Type | Description |
|---|---|---|
| days | integer | Lookback window in trade dates. Default 90, clamped to 1-730. |
| ticker* | string | Stock ticker symbol (e.g., "AAPL", "TSLA") |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"days": {
"type": "integer",
"description": "Lookback window in trade dates. Default 90, clamped to 1-730."
},
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., \"AAPL\", \"TSLA\")"
}
},
"additionalProperties": false
}Free: works without an API key or Pro plan (the hosted server only needs a signed-in account). One Signal8 Academy guide as Markdown, by track and slug (as returned by the Academy search, or from a signal8.ai/learn/<track>/<slug> URL). Returns title, description, section, lastVerified, the public url, the full Markdown body (links already rewritten to absolute signal8.ai URLs), the related guides, the glossary terms it uses (with one-line definitions) and its SEC sources (accession numbers). Guides use hypothetical examples ("Company X") unless a source is cited; they are education, not advice about any named company, and each guide's url is its citable source.
| Argument | Type | Description |
|---|---|---|
| slug* | string | Guide slug (kebab-case), e.g. "what-is-dilution", "s1-vs-s3-baby-shelf", "form-4-codes". |
| track* | string | Academy track: "dilution" (dilution & toxic financing), "filings" (reading SEC filings), "market-structure" (halts, short interest, float, splits, congressional trading), or "signal8" (using Signal8, its API and this MCP server). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"track",
"slug"
],
"properties": {
"slug": {
"type": "string",
"pattern": "^[\\da-z]+(?:-[\\da-z]+)*$",
"description": "Guide slug (kebab-case), e.g. \"what-is-dilution\", \"s1-vs-s3-baby-shelf\", \"form-4-codes\"."
},
"track": {
"enum": [
"dilution",
"filings",
"market-structure",
"signal8"
],
"type": "string",
"description": "Academy track: \"dilution\" (dilution & toxic financing), \"filings\" (reading SEC filings), \"market-structure\" (halts, short interest, float, splits, congressional trading), or \"signal8\" (using Signal8, its API and this MCP server)."
}
},
"additionalProperties": false
}Get the current stock quote for a company: price, volume, change, market cap and other real-time market data. Trading-halt fields halted, haltCode, haltReason, haltedAt and resumptionAt are present on every response (false/null when trading normally); a halted ticker returns the last-known quote instead of an error, or currentPrice null with halted true when nothing is recoverable. `priceAsOfDate` is the ET date the price printed (`priceAsOf` the trade time when known), not when it was read; null means the print date was not measured. `priceIsStale: true` means the price is an older held close (the last trade on that date), not a current trading price. `quoteSource: "screener_reference"` (foreign listings on US OTC that file nothing with the SEC, e.g. PGPHF) means `currentPrice` is a vendor reference price whose print date is not known, and every other market field is null (not measured). `marketCap` is the live price times the SEC-derived share count; when that count is unavailable it is null with `marketCapWithheldReason` set, which means not measured, not zero and not "no market cap". The count is `sharesOutstanding`, dated by `sharesOutstandingAsOf` and `sharesOutstandingAsOfKind` ("stated" = the issuer's statement date; "checked" = when it was last confirmed against a vendor; "none" = date not recorded), with a vendor-free `sharesOutstandingSource`. When no measured count exists, `sharesOutstanding` and `marketCap` are a best estimate (the newest dated filed or reference count, moved onto today's split basis): `sharesOutstandingEstimated: true`, `sharesOutstandingEstimateKind` and `marketCapEstimated: true` with `marketCapAsOf` (the count's date). Kind "stated_as_of" is the issuer's last stated count, a dated point rather than a bound or today's count; later issuances recorded in the filings are listed in `statedAsOf.events`, not added to it ("at_least" is the retired name of the same state).
| Argument | Type | Description |
|---|---|---|
| ticker* | string | Stock ticker symbol (e.g., "AAPL", "TSLA") |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., \"AAPL\", \"TSLA\")"
}
},
"additionalProperties": false
}Companies whose board still holds reverse-split authority it may use without another shareholder vote: an approval on file (shareholder vote or written consent; tracker states consent_pending, voted_approved, ratio_fixed) not past a stated expiry, one row per company (its newest approval; other live ones in otherLiveAuthorityEpisodeIds). Soonest stated expiry first. Each row is the Reverse Splits page row (ticker, companyName, ratio, exchange, approvalPath, domicile, splitAuthority, authorityTerms, sourceUrl / sourceAccession, sourceDocuments: every document behind the approval with accession or URL) plus an "authority" block: episodeId, state, approvedDate, approvedRatio {fixed, min, max} (the per-split ratio or range approved), cumulativeCap (cap on the product of every split drawn on it), multiStep, expiresOn, expiryTerm, daysUntilExpiry, and room: capRatio + capBasis ("cumulative_cap", or "single_split_maximum" = no cumulative cap stated and nothing drawn, so one split up to the approved maximum), perSplitMax, usedSplits + usedRatio (product of the splits already executed on it; 1 = none drawn), remainingRatio (capRatio / usedRatio), exhausted, nextSplitMax, pendingRatio (a ratio the board set that has not taken effect) and a one-line label. The approval route is approvalPath.path (shareholder_vote, written_consent, fpi_written_resolution, pre_approved_range, board_only, depositary_ratio_change or unknown = "Not determined", not "no vote"). Ratios are 1-for-N factors and combine by product. Not measured is not "none remaining": room.remainingRatio null comes with room.notMeasuredReason ("cumulative_cap_not_stated", "ratio_not_stated" or "drawn_split_ratio_not_stated"), meaning the remaining room is not measured for that reason. Such rows are listed, never dropped, and are not full. expiresOn null = the documents read state no expiry, not "never expires". An empty list is what the tracker has on file, not evidence that no board holds authority. This screen covers approvals on file; a board that may split under its statute or charter with no approval at all shows as splitAuthority.boardMayActWithoutVote on a row and in the per-company lifecycle, and is not listed here on that basis alone. Locked rows are withheld, not absent. The facts are part of Signal8 Pro: a key not owned by a Pro account gets rows with locked: true and only ticker, companyName, hasPage and exchange (access "preview", lockedCount). minRemaining and expiringBefore are Pro-only filters (on a non-Pro key they apply to unlocked rows only; filtersLimitedToUnlocked: true). A row whose remaining room or expiry is not measured never matches those filters; excludedNotMeasured counts how many were left out for that reason. Paging uses limit and nextCursor. available: false or an HTTP 503 FEATURE_DISABLED = unavailable, and the response says nothing about any company. The data describes what is on file and carries no view on whether a split will happen, what it means for the price, or what anyone should do.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Rows per page, 1 to 200 (default 50). |
| cursor | string | nextCursor from the previous page. Omit for the first page. |
| exchange | array | Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row. |
| minRemaining | number | Keep rows whose room.remainingRatio is at least this N (1-for-N), e.g. 50. Rows not measured never match. |
| expiringBefore | string | Keep rows whose stated expiresOn is before this YYYY-MM-DD day. Rows with no stated expiry never match. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Rows per page, 1 to 200 (default 50)."
},
"cursor": {
"type": "string",
"maxLength": 16,
"description": "nextCursor from the previous page. Omit for the first page."
},
"exchange": {
"type": "array",
"items": {
"enum": [
"NASDAQ",
"NYSE",
"AMEX",
"OTC",
"not_measured"
],
"type": "string"
},
"description": "Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row."
},
"minRemaining": {
"type": "number",
"minimum": 1,
"description": "Keep rows whose room.remainingRatio is at least this N (1-for-N), e.g. 50. Rows not measured never match."
},
"expiringBefore": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Keep rows whose stated expiresOn is before this YYYY-MM-DD day. Rows with no stated expiry never match."
}
},
"additionalProperties": false
}The reverse-split lifecycle Signal8 has tracked from a company's own SEC filings (proxies, 8-K Items 3.03/5.03/5.07, 6-Ks): one episode per split authority, newest first, each with its state (proposed, vote scheduled, approved, ratio set, effective date announced, charter filed, ... or closed), the ratio or authorised range, meeting / vote / effective dates, the state history, and the events behind it oldest first. Every event carries its source (accession and an EDGAR sourceUrl) and its facts; every stated fact carries the verbatim quote it was read from. Not stated means not measured, not "no": a fact with notStated:true (or a null field) means the documents read did not say it, not that it is false, zero or absent. coverage "unresolved" means the ticker could not be matched to an SEC registrant (not measured). coverage "tracked" with an empty episodes list means no episode has been tracked from the filings read since the tracker started; it is not evidence that no reverse split is planned. effectiveDate is the date the issuer stated, strictly parsed: a scheduled date, not a confirmation that the split happened (it can be postponed or abandoned). A conditional date ("the 25th trading day after the Trigger Event") is returned verbatim in effectiveCondition and is not a date; no date is computed from it. verification is copied from the tracker: "provisional" = one source, not cross-checked (the default, not "doubtful"); "verified" = cross-checked. Approval (present only when approvalAvailable is true): each episode carries approvalPath {path, label, quote, sourceUrl}: shareholder_vote, written_consent, fpi_written_resolution, pre_approved_range (the board set the ratio inside a range shareholders approved earlier), board_only (the company's own filing states no shareholder approval was required, quoted), depositary_ratio_change (an ADS ratio change by the depositary, no shareholder vote, the ordinary shares not consolidated) or unknown. The response also carries domicile {code, label, group, source} (EDGAR, else the latest 10-K / 20-F cover; null = not measured, not "Delaware") and splitAuthority {authority, basis, label, boardMayActWithoutVote, conditions, statute, quote, sourceUrl}. Only basis own_prior_board_only_announcement or charter_clause is board split authority on file: a charter clause is a standing power; own prior evidence is a PAST board-only split (dated in the label, conditional on its statute, e.g. NRS 78.207 needs authorized shares cut by the same ratio), not a power to skip a vote now, and the current split can still go to a vote. authority "unknown" or basis "domicile_default_only" is not a finding about the company: it only states what the domicile's law allows by default (e.g. "Domicile may permit board action; charter not checked"), not that this company can split without a vote. vote_required appears only as a labelled domicile default, not as a statement that a vote is needed. path "unknown" is not "no vote"; a missing proxy does not determine a path. An HTTP 503 FEATURE_DISABLED means the lifecycle tracker is switched off and the response says nothing about the company's splits.
| Argument | Type | Description |
|---|---|---|
| ticker* | string | US stock ticker, e.g. "ABCD" or "BRK.B". |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"maxLength": 12,
"minLength": 1,
"description": "US stock ticker, e.g. \"ABCD\" or \"BRK.B\"."
}
},
"additionalProperties": false
}The cross-company reverse-split lists the Signal8 Reverse Splits page serves, one view per call. view "upcoming" = splits with an effective date from tomorrow through 30 US market days ahead, the vendor market calendar union Signal8's SEC-filing tracker (filings, exchange and depositary notices); "recent" = the same union for effective dates in the past 30 days; "approved_no_date" = tracked episodes where shareholders (or the board, where no vote is required) have approved a reverse split but no effective date is stated yet; "vote_pending" = tracked episodes where a reverse split is proposed and the shareholder vote has not happened yet; "cancelled" = tracked episodes that ended without the split taking effect in the past 90 days (withdrawn by the company, a vote that did not approve it, an approved authority that expired unused, a meeting postponed indefinitely), with a cancelled object (outcome, outcomeLabel, endedOn, endedOnBasis, laterEpisode when the company has a newer open proposal) and the closing document as the source; older ended episodes are on the separate ended-reverse-splits tool. A security sits on exactly one of the first four views (upcoming, then recent, then approved_no_date, then vote_pending), with one exception: a split the company's own filing dates is on upcoming even when the same company also has a different, later split proposal awaiting a vote, which is then on vote_pending too; "cancelled" may repeat a company another view lists. Each row carries ticker, companyName, hasPage, source ("market_calendar" or "tracker"), stage + stageLabel, trackerState, ratio (or ratioMin / ratioMax for an authorised range), meetingDate, approvedDate, effectiveDate, effectiveDateSource, marketCalendarAgrees / marketCalendarDate / marketCalendarRatio, effectiveCondition, verification, marketConfirmation (recent only), marketCapUsd + capBucket, securityType, exchange, cik, sourceUrl / sourceAccession / sourceFormType / sourceFiledDate / sourceLabel, sourceDocuments (every document behind the episode), quote, adsRatioChange, approvalPath, domicile, splitAuthority and authorityTerms. Null means not measured or not stated: not "no split", not zero, not "no vote needed" and not "no date". A null ratio = the documents state none yet; a null marketCapUsd = cap not measured (capBucket is then null, not "nano"); a null verification = no tracked episode; a null domicile = not measured (not "Delaware"); a null marketConfirmation = the price step was not measured. An empty rows array on a view is normal and is not evidence that no company is splitting. completeness says what the view is: "scheduled_as_of_now" (upcoming) and "recorded_as_of_now" (recent) are what is known as of now, not "all reverse splits"; "tracked_episodes" is what the tracker has read from filings since it started, not every company. A scheduled split can still be postponed or cancelled: it is scheduled, not confirmed. Dates: effectiveDate is the scheduled effective date (vendor calendar, or the issuer-stated date strictly parsed from the filing); a filing or listing-rule deadline is not an effective date and does not appear in this field. A conditional date ("the 25th trading day after...") is returned verbatim in effectiveCondition and is not a date. effectiveDateSource says where effectiveDate came from: "filing" = the issuer stated it; "market_calendar" = the filing states no date and the vendor calendar supplies it. marketCalendarAgrees is a cross-check on a tracker row the calendar also lists: true = same date and ratio; false = at least one differs and marketCalendarDate / marketCalendarRatio hold the calendar's value (the filing's value is the row's value, and the two sources disagree); null or absent = not compared (no calendar row). meetingDate is the shareholder meeting date, not the split date. Approval and authority: approvalPath.path is shareholder_vote, written_consent, fpi_written_resolution, pre_approved_range (the board sets the ratio inside a range shareholders approved earlier), board_only (the issuer's own filing says no shareholder approval is required, quoted), depositary_ratio_change (an ADS ratio change by the depositary, no vote) or unknown ("Not determined", not "no vote"). splitAuthority.boardMayActWithoutVote is true only from the issuer's own filing or charter; a domicile default alone is not a finding. authorityTerms is the authority behind the episode: a cumulativeCap (the board may split in steps, each within the cap, without a new vote until the authority expires), multiStep, the expiry, and what executed splits already used; null = the documents state nothing beyond the ratio. Locked rows are withheld, not absent. The split facts on every view are part of Signal8 Pro. A caller whose API key is not owned by a Pro account gets every row with locked: true and only ticker, companyName, hasPage and exchange on it; the response then carries access: "preview", lockedCount (how many rows are locked) and rowLimit. A locked row means the facts exist and were not shown to this caller (they need Signal8 Pro); it does not mean "no split". access: "full" = every row carries its facts. filtersLimitedToUnlocked: true = a board / domicile filter was applied to unlocked rows only (locked rows are left out entirely, because matching them would reveal the fact through membership). Filters apply server-side: cap (scanner buckets), type (security type), exchange, board ("without_vote": board split authority on file, from the issuer's own filing or charter) and domicile. Each accepts "not_measured" to select rows where that fact was not measured; an unmeasured row never matches a measured bucket. totalCount is the filtered list (locked rows included), unfilteredCount the view before filters, capUnknownCount the rows whose cap was not measured (on the calendar views). Paging uses limit / offset; truncated: true = more rows exist. available: false with reason "tracker_not_enabled" (the three tracker views) means the tracker is switched off, not that nothing is pending. An HTTP 503 FEATURE_DISABLED means the page is switched off, and the response then says nothing about any company's split. The data describes what is on file and carries no view on whether a split will happen, what it means for the price, or what anyone should do.
| Argument | Type | Description |
|---|---|---|
| cap | array | Market-cap buckets to keep (the premarket scanner's): nano, micro, small, mid, large, or not_measured for rows whose cap was not measured. Empty = every row. |
| type | array | Security types to keep: common, adr (ADR / ADS), ordinary (foreign ordinary shares), other, or not_measured. Empty = every row. |
| view | string | Which list: "upcoming" (effective tomorrow through 30 market days ahead; the calendar UNION the tracker), "recent" (effective in the past 30 days), "approved_no_date" (approved, no effective date stated yet), "vote_pending" (proposed; the shareholder vote has not happened), "cancelled" (ended without taking effect in the past 90 days). Default "upcoming". |
| board | array | ["without_vote"] keeps only rows whose issuer can split without a shareholder vote on the evidence of its OWN filing or charter (a domicile default never matches). Pro-only fact: on a non-Pro key it applies to unlocked rows only. |
| limit | integer | Rows per page, 1 to 200 (default 50). |
| offset | integer | Rows to skip (default 0). Locked rows count towards paging. |
| domicile | array | Registrant domicile groups to keep: bvi, nevada, cayman, marshall_islands, bermuda, delaware, other, or not_measured. Pro-only fact: on a non-Pro key it applies to unlocked rows only. |
| exchange | array | Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"cap": {
"type": "array",
"items": {
"enum": [
"nano",
"micro",
"small",
"mid",
"large",
"not_measured"
],
"type": "string"
},
"description": "Market-cap buckets to keep (the premarket scanner's): nano, micro, small, mid, large, or not_measured for rows whose cap was not measured. Empty = every row."
},
"type": {
"type": "array",
"items": {
"enum": [
"common",
"adr",
"ordinary",
"other",
"not_measured"
],
"type": "string"
},
"description": "Security types to keep: common, adr (ADR / ADS), ordinary (foreign ordinary shares), other, or not_measured. Empty = every row."
},
"view": {
"enum": [
"upcoming",
"approved_no_date",
"vote_pending",
"recent",
"cancelled"
],
"type": "string",
"default": "upcoming",
"description": "Which list: \"upcoming\" (effective tomorrow through 30 market days ahead; the calendar UNION the tracker), \"recent\" (effective in the past 30 days), \"approved_no_date\" (approved, no effective date stated yet), \"vote_pending\" (proposed; the shareholder vote has not happened), \"cancelled\" (ended without taking effect in the past 90 days). Default \"upcoming\"."
},
"board": {
"type": "array",
"items": {
"enum": [
"without_vote"
],
"type": "string"
},
"description": "[\"without_vote\"] keeps only rows whose issuer can split without a shareholder vote on the evidence of its OWN filing or charter (a domicile default never matches). Pro-only fact: on a non-Pro key it applies to unlocked rows only."
},
"limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "Rows per page, 1 to 200 (default 50)."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Rows to skip (default 0). Locked rows count towards paging."
},
"domicile": {
"type": "array",
"items": {
"enum": [
"bvi",
"nevada",
"cayman",
"marshall_islands",
"bermuda",
"delaware",
"other",
"not_measured"
],
"type": "string"
},
"description": "Registrant domicile groups to keep: bvi, nevada, cayman, marshall_islands, bermuda, delaware, other, or not_measured. Pro-only fact: on a non-Pro key it applies to unlocked rows only."
},
"exchange": {
"type": "array",
"items": {
"enum": [
"NASDAQ",
"NYSE",
"AMEX",
"OTC",
"not_measured"
],
"type": "string"
},
"description": "Listing venues to keep: NASDAQ, NYSE, AMEX (NYSE American), OTC, or not_measured. Empty = every row."
}
},
"additionalProperties": false
}Get stock split history for a company including forward and reverse splits with dates, ratios, type classification, and cumulative 2-year reverse split ratio. Relevant for Nasdaq/NYSE minimum bid-price compliance (1:250 cumulative reverse-split cap). A null `cumulativeReverseSplitRatio2yr` means the cumulative cannot be stated, which is not the same as no reverse splits; `cumulativeWithheldReason` distinguishes the two. `unconfirmed_splits_in_window` means at least one in-window reverse split is evidenced by only one source, so no cumulative is defensible: the confirmed splits alone would understate it, and understating a cumulative can put an issuer that breaches the 1:250 cap under it. Each row also carries `confirmed`; a `confirmed: false` split appears only in the announcement calendar, which retains every announcement and retracts none, so it is usually an amended or superseded announcement and occasionally a real split the effected-splits ledger missed. Both are returned. `ratioDisplay` and `type` are likewise null for a ratio whose exact factor cannot be determined. Not every vendor "split" is a split: stock dividends and other distributions under 25%, spin-off price factors and consolidations under 1.5x are returned in `nonSplitAdjustments` (each with a `kind` and `meaning`), not in `splits`, and are excluded from `totalSplits`, `reverseSplitCount` and the cumulative. They are not splits.
| Argument | Type | Description |
|---|---|---|
| ticker* | string | Stock ticker symbol (e.g., AAPL, TSLA) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., AAPL, TSLA)"
}
},
"additionalProperties": false
}Get how one ticker's price moved in the N calendar days after each stock split it already executed (forward or reverse), newest first, up to 30 splits, in one call. Past executed splits only: upcoming, approved or pending splits are not included. Each split row carries executionDate, ratio ("1-for-12" = 12 old shares became 1), kind (reverse | forward | other), lastPreSplitDate, firstPostSplitDate, firstPostSplitCloseAsTraded, windowEndDate, windowEndCloseAsTraded, sessionsInWindow, changeFromFirstPostSplitClosePct (first post-split close to the last close in the window), changeFromLastPreSplitClosePct (the last pre-split close moved onto the post-split basis by the split ratio, so the split itself is not counted as a move), lowestLowVsFirstClosePct and highestHighVsFirstClosePct. Basis: the response field basis states it. Each row is on that split's own post-split basis (daily bars as traded); prices are not adjusted onto today's basis, so % moves are comparable across rows and prices are not. A null value means not measured; it does not mean 0 or "no move". Causes: a missing bar, a bar print Signal8 refused as implausible, or a window that reaches a later split (anotherSplitInWindow: true, its % withheld). notMeasured on a row names the reason per null field; dataGap = no daily bar within 7 days after the split. Stock dividends, spin-off price factors and consolidations under 1.5x that the vendor files as splits are not splits: they are listed in nonSplitAdjustments (kind, meaning), never measured or counted, and a split window containing one has its % withheld (nonSplitAdjustmentInWindow: true). An empty splits array means no executed split is on record in Signal8 split history, which is not evidence that none occurred. splitsMeasured and fellInWindow count only measured rows. asOf is the latest window-end bar date. These are past price moves, not a forecast and not investment advice. Included in Signal8 Pro: an HTTP 403 FEATURE_NOT_AVAILABLE means the API key's account is not on Pro, and the response then carries no price data for the company.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Most recent executed splits to measure, 1 to 30 (default 20). |
| ticker* | string | US stock ticker, e.g. "TOPS". |
| windowDays | integer | Calendar days after each split to measure, 1 to 365 (default 30). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ticker"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 30,
"minimum": 1,
"description": "Most recent executed splits to measure, 1 to 30 (default 20)."
},
"ticker": {
"type": "string",
"maxLength": 12,
"minLength": 1,
"description": "US stock ticker, e.g. \"TOPS\"."
},
"windowDays": {
"type": "integer",
"maximum": 365,
"minimum": 1,
"description": "Calendar days after each split to measure, 1 to 365 (default 30)."
}
},
"additionalProperties": false
}Reverse stock splits scheduled to take effect within a day-offset window of the current US market day, for companies under a market-cap ceiling. Offsets are days from today on the US market calendar: fromOffset=1, toOffset=1 is tomorrow; fromOffset=1, toOffset=7 is the week ahead. Each row carries the ticker, company name, the exact vendor integers (splitFrom/splitTo), a pre-rendered ratio ("1-for-20"), the effective date, market cap, float in shares, and price. floatShares is on the same split basis as the market cap. floatBasis says what it is: "measured", or "estimate" / "estimate_rebased" (the float ladder's point estimate, moved across this split when it predates it), i.e. an estimate rather than a measurement. floatShares: null means not measured or withheld, not zero and not "no float"; such rows are included (they have a valid market cap) and floatWithheldReason gives the reason. floatUnknownCount counts those null-float rows in the list; it is not a withholding count (withheldCount is). price is on the same split basis as the market cap (null when it cannot be stated on one basis), so it is not comparable with a pre-split price from elsewhere. Rows are splits scheduled as of now, not a guarantee that every split effective in the window is already known: the underlying stock_splits table has no created_at column, so when a row first appeared is unmeasurable, and a split announced later is simply missing. The result is "scheduled as of now", not "all" reverse splits. A scheduled split can also be postponed or cancelled after it is announced. capUnknownCount is a withholding count, not a zero: it counts rows that passed every other filter and were deliberately excluded because Signal8 has no measured market cap for them (typically real OTC microcaps). It does not mean those companies have no dilution, no split or no cap; the cap was not measured, so they cannot be asserted to sit under the stated ceiling, and with capUnknownCount above zero the list is not complete for an "under $Xm" framing. Funds, ETFs and sub-1.5x fractional ratio adjustments are already removed server-side, and the ratio is the vendor's. An empty splits array is a normal, common result: most single weekdays have no sub-cap reverse split scheduled at all. It is not an error, not a failure and not evidence that reverse-split activity has stopped. includeLifecycle=true adds Signal8's SEC-filing lifecycle tracker: top-level lifecycleAvailable, and per row `lifecycle` = the tracked episode (state, ratio, ratioRange, meetingDate, the issuer-stated effectiveDate, effectiveCondition, verification, asOf, sourceUrl). lifecycle: null means no episode tracked, not "no split" and not a contradiction of the calendar row; a row with no lifecycle key could not be matched to an SEC registrant (not measured). lifecycleAvailable: false means the tracker is switched off or unreadable, so the response carries no lifecycle information. verification "provisional" = one source, not cross-checked. Scope: this is the vendor market calendar only. The merged list the Signal8 Reverse Splits page shows (the calendar union the SEC-filing tracker, one row per security, with the stage, approval route, authority terms, source filings and the Approved-no-date / Vote-pending tabs) is a separate cross-company list.
| Argument | Type | Description |
|---|---|---|
| toOffset | integer | Window end, inclusive, as a day offset from the US market day (default 1). Use 7 with fromOffset 1 for the week ahead. |
| fromOffset | integer | Window start as a day offset from the US market day (default 1 = tomorrow). Must be <= toOffset; an inverted window is rejected rather than silently returning an empty list. |
| maxMarketCap | number | Exclusive market-cap ceiling in USD (default 300000000). Rows with NO measured market cap are excluded and counted in capUnknownCount, never assumed to be under the ceiling. |
| includeLifecycle | boolean | Attach the tracked SEC-filing lifecycle episode to each row (default false). null = no episode tracked, never "no split"; a missing key = not matched to a registrant (not measured). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"toOffset": {
"type": "integer",
"default": 1,
"maximum": 30,
"minimum": -30,
"description": "Window end, inclusive, as a day offset from the US market day (default 1). Use 7 with fromOffset 1 for the week ahead."
},
"fromOffset": {
"type": "integer",
"default": 1,
"maximum": 30,
"minimum": -30,
"description": "Window start as a day offset from the US market day (default 1 = tomorrow). Must be <= toOffset; an inverted window is rejected rather than silently returning an empty list."
},
"maxMarketCap": {
"type": "number",
"default": 300000000,
"description": "Exclusive market-cap ceiling in USD (default 300000000). Rows with NO measured market cap are excluded and counted in capUnknownCount, never assumed to be under the ceiling.",
"exclusiveMinimum": 0
},
"includeLifecycle": {
"type": "boolean",
"description": "Attach the tracked SEC-filing lifecycle episode to each row (default false). null = no episode tracked, never \"no split\"; a missing key = not matched to a registrant (not measured)."
}
},
"additionalProperties": false
}Look up a filing or exhibit by its SEC accession number. Supports both dashed format (e.g., "0001193125-22-010026") and compact 18-digit format. Returns filing metadata including company name, form type, filing date, exhibit count and `filingId` (the internal id of the stored filing). If the filing is held in Signal8's archive (isInDatabase: true) its content is readable through that filingId; if it is only found on SEC EDGAR the response has isInDatabase: false and basic metadata only.
| Argument | Type | Description |
|---|---|---|
| accessionNumber* | string | SEC accession number in dashed (e.g., "0001193125-22-010026") or compact 18-digit format |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"accessionNumber"
],
"properties": {
"accessionNumber": {
"type": "string",
"description": "SEC accession number in dashed (e.g., \"0001193125-22-010026\") or compact 18-digit format"
}
},
"additionalProperties": false
}Search for companies by name or ticker symbol in the Signal8 database. Returns matching companies with their ticker, name, CIK, and exchange.
| Argument | Type | Description |
|---|---|---|
| limit | number | Maximum results to return (default: 10, max: 50) |
| query* | string | Search query - company name or ticker symbol (e.g., "Tesla", "TSLA") |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"limit": {
"type": "number",
"maximum": 50,
"minimum": 1,
"description": "Maximum results to return (default: 10, max: 50)"
},
"query": {
"type": "string",
"description": "Search query - company name or ticker symbol (e.g., \"Tesla\", \"TSLA\")"
}
},
"additionalProperties": false
}Full-text search across SEC filing content that returns the matching passage: one match per filing, with the exhibit it was found in (`exhibit_id`, `exhibit_type`) and a snippet with context. Query syntax: unquoted words all have to appear (any order, any distance); "quoted phrase" = exact wording; OR between alternatives (merger OR acquisition); -word or -"phrase" to exclude; w1 NEAR/10 w2 (also NEAR(10), or bare NEAR = within 10) = words close together; word* = prefix of 4+ letters (dilut* matches dilution, dilutive); $AAPL or a capitalised ticker scopes to that company; a form code (8-K, 10-Q, S-1), "item 5.02" / "8-K 1.05" and a bare year (2024) scope to that form / 8-K item / year. Quoted multi-word phrases match as phrases; the archive's reading of the query is in meta.understanding. Suited to locating specific clauses ("change of control", "anti-dilution", "right of first refusal") and to the excerpt of a known filing (accessionNumber or filingId). It has no filing-level paging, totals, date ranges, 8-K item, excluded-form or company filters. Filters: CIK, filing, accession number, form type, section (risk_factors, mdna, ex99 …; applied only when meta.sections confirms it, otherwise meta.unsupported says the whole filing was searched) and exhibitTypes (EX-10 …). Coverage: Signal8's SEC EDGAR archive, updated through the day, in its held range (see `archiveFrom` in each response; currently from late 2021, expanding back to 2016 as the history backfill fills in). Before archiveFrom it holds only a scatter, so absence before archiveFrom is not evidence a filing was never filed; SEC EDGAR itself covers earlier periods. Record-only rows (bodyStored: false) have no stored body; the document is at its sec.gov URL.
| Argument | Type | Description |
|---|---|---|
| cik | string | Filter to a specific company by CIK number |
| sort | string | Result order: newest (default) or relevance (best match first) |
| limit | number | Max results (default: 20, max: 100) |
| match | string | Word matching. exact = a word matches only itself ("split" does not match "splits"), which is EDGAR full-text search's behaviour; stemmed = English word variations also match. Default when omitted: stemmed. The mode actually applied is reported in the response's meta.matchMode. |
| facets | boolean | true = also return `facets` { forms, years, items }: [{ value, count }] over the whole match set. Absent when not measured (not zero). Default false. |
| pattern* | string | Search query (minimum 2 characters): "exact phrase", OR, -exclude, w1 NEAR/n w2, word*, $TICKER. A CIK/filing-scoped search whose text is not indexed yet falls back to a literal case-insensitive substring match (response engine: "substring"); there each "quoted phrase" and bare word must appear (quotes stripped), and meta.substringTerms lists the terms matched. OR, NEAR, -exclude and word* are not applied on that path. |
| section | string | Restricts matching to sections (comma-separated): business, risk_factors, cybersecurity, legal_proceedings, mdna, market_risk, controls (10-K/10-Q/20-F narrative items, by meaning: mdna is 10-K Item 7, 10-Q Part I Item 2 and 20-F Item 5), ex99 (press-release / EX-99.x exhibit text) and item_X_YY (the text under an 8-K item, e.g. item_5_02). Aliases: mda, risk, legal, cyber, press_release, 5.02. Unknown names are a 400. Requires q. Applied only when the response's meta.sections names it; otherwise meta.unsupported says why (e.g. the archive index does not have sections yet) and matches may come from anywhere in the filing. |
| filingId | string | Filter to a specific filing by internal ID |
| formType | string | Filter by form type (e.g., "10-K", "S-1") |
| understand | boolean | Query understanding (default true): tickers/$TICKER, company names, form codes, "item N.NN" and synonym expansion, reported in meta.understanding. false = match the words literally. |
| exhibitTypes | string | Keeps only filings carrying any of these exhibit types (comma-separated): a family such as EX-10 (material contracts) matches every member (EX-10.1, EX-10.2…); an exact type such as EX-99.1 (usually the press release) only itself. Others: EX-97 clawback policy, EX-3 charter/bylaws, EX-4 instruments/warrants, EX-21 subsidiaries, EX-23 consents. "10.1" is accepted for EX-10.1. Listed in appliedFilters when the rows prove it; otherwise in ignoredFilters / meta.unsupported, and the rows are then unfiltered. |
| snippetLength | number | Characters of context around each match (default: 200) |
| accessionNumber | string | Filter to a specific filing by SEC accession number |
| matchedSections | boolean | Per-row `matchedSections` (default true): the sections the text matched in. Absent on a row means not measured (index without sections), not "matched nowhere". |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"pattern"
],
"properties": {
"cik": {
"type": "string",
"description": "Filter to a specific company by CIK number"
},
"sort": {
"enum": [
"newest",
"relevance"
],
"type": "string",
"description": "Result order: newest (default) or relevance (best match first)"
},
"limit": {
"type": "number",
"maximum": 100,
"minimum": 1,
"description": "Max results (default: 20, max: 100)"
},
"match": {
"enum": [
"exact",
"stemmed"
],
"type": "string",
"description": "Word matching. exact = a word matches only itself (\"split\" does not match \"splits\"), which is EDGAR full-text search's behaviour; stemmed = English word variations also match. Default when omitted: stemmed. The mode actually applied is reported in the response's meta.matchMode."
},
"facets": {
"type": "boolean",
"description": "true = also return `facets` { forms, years, items }: [{ value, count }] over the whole match set. Absent when not measured (not zero). Default false."
},
"pattern": {
"type": "string",
"minLength": 2,
"description": "Search query (minimum 2 characters): \"exact phrase\", OR, -exclude, w1 NEAR/n w2, word*, $TICKER. A CIK/filing-scoped search whose text is not indexed yet falls back to a literal case-insensitive substring match (response engine: \"substring\"); there each \"quoted phrase\" and bare word must appear (quotes stripped), and meta.substringTerms lists the terms matched. OR, NEAR, -exclude and word* are not applied on that path."
},
"section": {
"type": "string",
"maxLength": 400,
"description": "Restricts matching to sections (comma-separated): business, risk_factors, cybersecurity, legal_proceedings, mdna, market_risk, controls (10-K/10-Q/20-F narrative items, by meaning: mdna is 10-K Item 7, 10-Q Part I Item 2 and 20-F Item 5), ex99 (press-release / EX-99.x exhibit text) and item_X_YY (the text under an 8-K item, e.g. item_5_02). Aliases: mda, risk, legal, cyber, press_release, 5.02. Unknown names are a 400. Requires q. Applied only when the response's meta.sections names it; otherwise meta.unsupported says why (e.g. the archive index does not have sections yet) and matches may come from anywhere in the filing."
},
"filingId": {
"type": "string",
"description": "Filter to a specific filing by internal ID"
},
"formType": {
"type": "string",
"description": "Filter by form type (e.g., \"10-K\", \"S-1\")"
},
"understand": {
"type": "boolean",
"description": "Query understanding (default true): tickers/$TICKER, company names, form codes, \"item N.NN\" and synonym expansion, reported in meta.understanding. false = match the words literally."
},
"exhibitTypes": {
"type": "string",
"maxLength": 400,
"description": "Keeps only filings carrying any of these exhibit types (comma-separated): a family such as EX-10 (material contracts) matches every member (EX-10.1, EX-10.2…); an exact type such as EX-99.1 (usually the press release) only itself. Others: EX-97 clawback policy, EX-3 charter/bylaws, EX-4 instruments/warrants, EX-21 subsidiaries, EX-23 consents. \"10.1\" is accepted for EX-10.1. Listed in appliedFilters when the rows prove it; otherwise in ignoredFilters / meta.unsupported, and the rows are then unfiltered."
},
"snippetLength": {
"type": "number",
"maximum": 1000,
"minimum": 50,
"description": "Characters of context around each match (default: 200)"
},
"accessionNumber": {
"type": "string",
"description": "Filter to a specific filing by SEC accession number"
},
"matchedSections": {
"type": "boolean",
"description": "Per-row `matchedSections` (default true): the sections the text matched in. Absent on a row means not measured (index without sections), not \"matched nowhere\"."
}
},
"additionalProperties": false
}Free: works without an API key or Pro plan (the hosted server only needs a signed-in account). Searches the Signal8 Academy (signal8.ai/learn): plain-English guides that explain dilution (ATMs, warrants, convertibles, baby shelf, cash runway), how to read SEC filings (8-K items, Form 4 codes, 13D/13G, 424B5, S-1/S-3), market structure (halts, short interest, float, reverse splits, STOCK Act disclosures) and how Signal8 works. Returns matching guides with title, description, track, section, reading time, lastVerified date, the public url and the signal8:// resource uri, without bodies. Keyword match: every query word must appear somewhere in the guide; title hits rank highest. An empty query lists every guide (optionally one track) in reading order. An empty result means no guide matched the words given (fewer or broader words match more guides, e.g. "warrant" rather than "warrant inducement repricing"), not that the topic is unimportant.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Maximum guides to return (1-50, default 10). |
| query | string | Words to search for, e.g. "baby shelf", "form 4", "reverse split". Empty string lists every guide. |
| track | string | Optional. Restrict to one Academy track: "dilution" (dilution & toxic financing), "filings" (reading SEC filings), "market-structure" (halts, short interest, float, splits, congressional trading), or "signal8" (using Signal8, its API and this MCP server). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Maximum guides to return (1-50, default 10)."
},
"query": {
"type": "string",
"default": "",
"maxLength": 200,
"description": "Words to search for, e.g. \"baby shelf\", \"form 4\", \"reverse split\". Empty string lists every guide."
},
"track": {
"enum": [
"dilution",
"filings",
"market-structure",
"signal8"
],
"type": "string",
"description": "Optional. Restrict to one Academy track: \"dilution\" (dilution & toxic financing), \"filings\" (reading SEC filings), \"market-structure\" (halts, short interest, float, splits, congressional trading), or \"signal8\" (using Signal8, its API and this MCP server)."
}
},
"additionalProperties": false
}Search and list SEC filings by company (CIK), form type, date range, 8-K item codes and excluded forms, optionally with a full-text query over filing bodies and by company facts (market cap, float, price, sector, industry, exchange, company type, foreign issuer, recent IPO). Rows carry `id` (the internal filingId used by the filing-document and exhibit tools), cik, company_name, accession_number, form_type, filing_date, acceptedAt, primaryDocument, bodyStored and itemNumbers (plus `rank` and `snippet` with `q`); `pagination` has `total`, `totalRelation` ("eq" exact; "gte" a lower bound cut at 10,000, when `totalEstimate` is "about N"), `hasMore` and `nextCursor`. The `ciks` filter matches the filing's own CIK: a Form 4 filed under the reporting owner's CIK is not returned for the issuer's CIK. Coverage: Signal8's SEC EDGAR archive, updated through the day, in its held range (see `archiveFrom` in each response; currently from late 2021, expanding back to 2016 as the history backfill fills in). Before archiveFrom it holds only a scatter, so absence before archiveFrom is not evidence a filing was never filed; SEC EDGAR itself covers earlier periods. Record-only rows (bodyStored: false) have no stored body; the document is at its sec.gov URL. Every response carries `archiveFrom` and `rangeStartsBeforeArchive`: a range with no dateFrom or starting before archiveFrom is not definitive (`searchIndex.complete: false`, `reason: "outside_held_range"`, `heldFrom`): an empty result then means the archive holds no match from archiveFrom onward, not that no such filing exists. An empty text result is definitive only when `searchIndex.complete` is true. Full-text `q`: Query syntax: unquoted words all have to appear (any order, any distance); "quoted phrase" = exact wording; OR between alternatives (merger OR acquisition); -word or -"phrase" to exclude; w1 NEAR/10 w2 (also NEAR(10), or bare NEAR = within 10) = words close together; word* = prefix of 4+ letters (dilut* matches dilution, dilutive); $AAPL or a capitalised ticker scopes to that company; a form code (8-K, 10-Q, S-1), "item 5.02" / "8-K 1.05" and a bare year (2024) scope to that form / 8-K item / year. The archive's reading of the query is in `meta.understanding` (understand=false searches the words literally). facets=true adds `facets` per form / year / 8-K item over the whole result set (absent = not measured, never zero). sort=relevance caps page 1 per company; meta.diversity {maxPerCompany, hidden} names who has more (page with nextCursor or filter by CIK). section / exhibitTypes filters apply only when meta.sections / appliedFilters confirm them; otherwise meta.unsupported says why and the whole filing was searched. Company filters (minMarketCap … recentIpo): only issuer-filed forms are searched (third-party Form 4 / 144 / 13D/G go to `companyFilter.droppedForms` unless `companyFilter.subjectMatch` is true; with no formTypes the default is 10-K, 10-Q, 8-K, S-1, S-3, DEF 14A, 20-F, 40-F, 6-K); companies with no measured value are excluded, never assumed (`companyFilter.unknown` counts them); an unknown value is a 400 listing allowed names; when the archive cannot answer, the call fails with COMPANY_FILTER_NOT_APPLIED and never returns unfiltered rows; results are cursor-paged, cannot combine with acceptedFrom/acceptedTo/bodyStored, and carry no snippet. Results are filings, not a company list or count.
| Argument | Type | Description |
|---|---|---|
| q | string | Full-text query over filing bodies. Query syntax: unquoted words all have to appear (any order, any distance); "quoted phrase" = exact wording; OR between alternatives (merger OR acquisition); -word or -"phrase" to exclude; w1 NEAR/10 w2 (also NEAR(10), or bare NEAR = within 10) = words close together; word* = prefix of 4+ letters (dilut* matches dilution, dilutive); $AAPL or a capitalised ticker scopes to that company; a form code (8-K, 10-Q, S-1), "item 5.02" / "8-K 1.05" and a bare year (2024) scope to that form / 8-K item / year. Example: '$AAPL "share repurchase" -"no longer"', 'cyber* NEAR/10 incident', 'item 5.02 resign*'. |
| ciks | string | Comma-separated CIK numbers to filter by (e.g., "320193,1018724"; zero-padded also accepted) |
| page | number | Page number (1-indexed, default: 1). Ignored when cursor is set; not allowed with company filters. |
| sort | string | newest (by acceptance time, default) or relevance (requires q; best match first) |
| items | string | Comma-separated 8-K item codes, all required (e.g., "2.02,9.01" = results + financial statements; "5.02" = officer/director changes; "1.01" = material agreements; "3.01" = delisting notice). |
| match | string | Word matching for q. exact = a word matches only itself ("split" does not match "splits" or "splitting"), which is EDGAR full-text search's own behaviour; stemmed = English word variations also match. Default when omitted: stemmed. The mode actually applied is in the response's meta.matchMode (with meta.matchModeFallbackReason when it differs from the one asked for); meta.engine names the search engine. Ignored without q. |
| cursor | string | Opaque keyset cursor from a previous response's pagination.nextCursor. Stable for deep paging while new filings arrive (page is not). Required for page 2+ of a company-filtered search. |
| dateTo | string | End filing date (YYYY-MM-DD) |
| facets | boolean | true = also return `facets`: { forms, years, items }, each a list of { value, count } over the whole result set (not just this page). Present only when the archive measured them (its OpenSearch engine); absent means not measured, not zero. Default false. |
| section | string | Restricts matching to sections (comma-separated): business, risk_factors, cybersecurity, legal_proceedings, mdna, market_risk, controls (10-K/10-Q/20-F narrative items, by meaning: mdna is 10-K Item 7, 10-Q Part I Item 2 and 20-F Item 5), ex99 (press-release / EX-99.x exhibit text) and item_X_YY (the text under an 8-K item, e.g. item_5_02). Aliases: mda, risk, legal, cyber, press_release, 5.02. Unknown names are a 400. Requires q. Applied only when the response's meta.sections names it; otherwise meta.unsupported says why (e.g. the archive index does not have sections yet) and matches may come from anywhere in the filing. |
| sectors | string | Company filter. Sector names separated by "|" (or a bare comma), exact and case-sensitive (e.g. "Healthcare|Technology"). An unknown name returns a 400 listing every valid sector. |
| dateFrom | string | Start filing date (YYYY-MM-DD). The archive only holds filings from its `archiveFrom` date (stated in every response; currently late 2021, expanding back to 2016): omitting dateFrom, or starting earlier, makes an empty result non-definitive. |
| maxFloat | number | Company filter. Maximum public float, in shares |
| maxPrice | number | Company filter. Maximum latest share price in USD |
| minFloat | number | Company filter. Minimum public float, in shares |
| minPrice | number | Company filter. Minimum latest share price in USD |
| pageSize | number | Results per page (default: 25, max: 100) |
| exchanges | string | Company filter. Comma-separated listing venues: NASDAQ, NYSE, AMEX (= NYSE American), OTC |
| formTypes | string | Comma-separated form types (e.g., "10-K,10-Q,8-K,S-1,S-3,424B5"). Exact match; amendments (e.g. "10-K/A") match only when listed. (With company filters, amendments are added automatically.) |
| recentIpo | boolean | Company filter. true = first listed within the last 365 days, with no evidence of earlier public status (renames and relistings are excluded). false is the same as omitting it. |
| industries | string | Company filter. Industry names separated by "|", exact and case-sensitive (e.g. "Biotechnology|Airlines, Airports & Air Services"; some names contain ", ", so "|" is the safe separator; a bare comma with no space after it also separates). An unknown name returns a 400 listing every valid industry. |
| understand | boolean | Query understanding (default true): the archive recognises tickers/$TICKER, company names, form codes, "item N.NN" and expands synonyms, reporting what it applied in meta.understanding. false = search the words literally (also disables synonym expansion). Ignored without q. |
| companyTypes | string | Company filter. Comma-separated: operating, fund (registered funds/ETFs; adds N-CSR, N-CEN, N-PX, 485BPOS, 497/497K to the default forms), spac (blank-check companies) |
| excludeForms | string | Comma-separated form types to exclude (e.g., "4,13F-HR"). Exact match. |
| exhibitTypes | string | Keeps only filings carrying any of these exhibit types (comma-separated): a family such as EX-10 (material contracts) matches every member (EX-10.1, EX-10.2…); an exact type such as EX-99.1 (usually the press release) only itself. Others: EX-97 clawback policy, EX-3 charter/bylaws, EX-4 instruments/warrants, EX-21 subsidiaries, EX-23 consents. "10.1" is accepted for EX-10.1. Listed in appliedFilters when the rows prove it; otherwise in ignoredFilters / meta.unsupported, and the rows are then unfiltered. |
| maxMarketCap | number | Company filter. Maximum market cap in USD, e.g. 300000000 for under $300M |
| minMarketCap | number | Company filter. Minimum market cap in USD (price × shares outstanding), e.g. 50000000 for $50M |
| foreignIssuer | boolean | Company filter. true = companies with foreign-issuer evidence (a 20-F, 40-F or 6-K seen, or an ADR listing); false = none seen since the evidence log began (companyFilter.foreignEvidenceSince) |
| matchedSections | boolean | Per-row `matchedSections` (default true): the sections the text matched in. Absent on a row means not measured (index without sections), not "matched nowhere". Ignored without q. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"q": {
"type": "string",
"maxLength": 500,
"description": "Full-text query over filing bodies. Query syntax: unquoted words all have to appear (any order, any distance); \"quoted phrase\" = exact wording; OR between alternatives (merger OR acquisition); -word or -\"phrase\" to exclude; w1 NEAR/10 w2 (also NEAR(10), or bare NEAR = within 10) = words close together; word* = prefix of 4+ letters (dilut* matches dilution, dilutive); $AAPL or a capitalised ticker scopes to that company; a form code (8-K, 10-Q, S-1), \"item 5.02\" / \"8-K 1.05\" and a bare year (2024) scope to that form / 8-K item / year. Example: '$AAPL \"share repurchase\" -\"no longer\"', 'cyber* NEAR/10 incident', 'item 5.02 resign*'."
},
"ciks": {
"type": "string",
"description": "Comma-separated CIK numbers to filter by (e.g., \"320193,1018724\"; zero-padded also accepted)"
},
"page": {
"type": "number",
"minimum": 1,
"description": "Page number (1-indexed, default: 1). Ignored when cursor is set; not allowed with company filters."
},
"sort": {
"enum": [
"newest",
"relevance"
],
"type": "string",
"description": "newest (by acceptance time, default) or relevance (requires q; best match first)"
},
"items": {
"type": "string",
"description": "Comma-separated 8-K item codes, all required (e.g., \"2.02,9.01\" = results + financial statements; \"5.02\" = officer/director changes; \"1.01\" = material agreements; \"3.01\" = delisting notice)."
},
"match": {
"enum": [
"exact",
"stemmed"
],
"type": "string",
"description": "Word matching for q. exact = a word matches only itself (\"split\" does not match \"splits\" or \"splitting\"), which is EDGAR full-text search's own behaviour; stemmed = English word variations also match. Default when omitted: stemmed. The mode actually applied is in the response's meta.matchMode (with meta.matchModeFallbackReason when it differs from the one asked for); meta.engine names the search engine. Ignored without q."
},
"cursor": {
"type": "string",
"description": "Opaque keyset cursor from a previous response's pagination.nextCursor. Stable for deep paging while new filings arrive (page is not). Required for page 2+ of a company-filtered search."
},
"dateTo": {
"type": "string",
"description": "End filing date (YYYY-MM-DD)"
},
"facets": {
"type": "boolean",
"description": "true = also return `facets`: { forms, years, items }, each a list of { value, count } over the whole result set (not just this page). Present only when the archive measured them (its OpenSearch engine); absent means not measured, not zero. Default false."
},
"section": {
"type": "string",
"maxLength": 400,
"description": "Restricts matching to sections (comma-separated): business, risk_factors, cybersecurity, legal_proceedings, mdna, market_risk, controls (10-K/10-Q/20-F narrative items, by meaning: mdna is 10-K Item 7, 10-Q Part I Item 2 and 20-F Item 5), ex99 (press-release / EX-99.x exhibit text) and item_X_YY (the text under an 8-K item, e.g. item_5_02). Aliases: mda, risk, legal, cyber, press_release, 5.02. Unknown names are a 400. Requires q. Applied only when the response's meta.sections names it; otherwise meta.unsupported says why (e.g. the archive index does not have sections yet) and matches may come from anywhere in the filing."
},
"sectors": {
"type": "string",
"description": "Company filter. Sector names separated by \"|\" (or a bare comma), exact and case-sensitive (e.g. \"Healthcare|Technology\"). An unknown name returns a 400 listing every valid sector."
},
"dateFrom": {
"type": "string",
"description": "Start filing date (YYYY-MM-DD). The archive only holds filings from its `archiveFrom` date (stated in every response; currently late 2021, expanding back to 2016): omitting dateFrom, or starting earlier, makes an empty result non-definitive."
},
"maxFloat": {
"type": "number",
"minimum": 0,
"description": "Company filter. Maximum public float, in shares"
},
"maxPrice": {
"type": "number",
"minimum": 0,
"description": "Company filter. Maximum latest share price in USD"
},
"minFloat": {
"type": "number",
"minimum": 0,
"description": "Company filter. Minimum public float, in shares"
},
"minPrice": {
"type": "number",
"minimum": 0,
"description": "Company filter. Minimum latest share price in USD"
},
"pageSize": {
"type": "number",
"maximum": 100,
"minimum": 1,
"description": "Results per page (default: 25, max: 100)"
},
"exchanges": {
"type": "string",
"description": "Company filter. Comma-separated listing venues: NASDAQ, NYSE, AMEX (= NYSE American), OTC"
},
"formTypes": {
"type": "string",
"description": "Comma-separated form types (e.g., \"10-K,10-Q,8-K,S-1,S-3,424B5\"). Exact match; amendments (e.g. \"10-K/A\") match only when listed. (With company filters, amendments are added automatically.)"
},
"recentIpo": {
"type": "boolean",
"description": "Company filter. true = first listed within the last 365 days, with no evidence of earlier public status (renames and relistings are excluded). false is the same as omitting it."
},
"industries": {
"type": "string",
"description": "Company filter. Industry names separated by \"|\", exact and case-sensitive (e.g. \"Biotechnology|Airlines, Airports & Air Services\"; some names contain \", \", so \"|\" is the safe separator; a bare comma with no space after it also separates). An unknown name returns a 400 listing every valid industry."
},
"understand": {
"type": "boolean",
"description": "Query understanding (default true): the archive recognises tickers/$TICKER, company names, form codes, \"item N.NN\" and expands synonyms, reporting what it applied in meta.understanding. false = search the words literally (also disables synonym expansion). Ignored without q."
},
"companyTypes": {
"type": "string",
"description": "Company filter. Comma-separated: operating, fund (registered funds/ETFs; adds N-CSR, N-CEN, N-PX, 485BPOS, 497/497K to the default forms), spac (blank-check companies)"
},
"excludeForms": {
"type": "string",
"description": "Comma-separated form types to exclude (e.g., \"4,13F-HR\"). Exact match."
},
"exhibitTypes": {
"type": "string",
"maxLength": 400,
"description": "Keeps only filings carrying any of these exhibit types (comma-separated): a family such as EX-10 (material contracts) matches every member (EX-10.1, EX-10.2…); an exact type such as EX-99.1 (usually the press release) only itself. Others: EX-97 clawback policy, EX-3 charter/bylaws, EX-4 instruments/warrants, EX-21 subsidiaries, EX-23 consents. \"10.1\" is accepted for EX-10.1. Listed in appliedFilters when the rows prove it; otherwise in ignoredFilters / meta.unsupported, and the rows are then unfiltered."
},
"maxMarketCap": {
"type": "number",
"minimum": 0,
"description": "Company filter. Maximum market cap in USD, e.g. 300000000 for under $300M"
},
"minMarketCap": {
"type": "number",
"minimum": 0,
"description": "Company filter. Minimum market cap in USD (price × shares outstanding), e.g. 50000000 for $50M"
},
"foreignIssuer": {
"type": "boolean",
"description": "Company filter. true = companies with foreign-issuer evidence (a 20-F, 40-F or 6-K seen, or an ADR listing); false = none seen since the evidence log began (companyFilter.foreignEvidenceSince)"
},
"matchedSections": {
"type": "boolean",
"description": "Per-row `matchedSections` (default true): the sections the text matched in. Absent on a row means not measured (index without sections), not \"matched nowhere\". Ignored without q."
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 9, 2026.
A very long tool description (over 4,000 characters) is hard to review and easy to hide instructions in.
Fix: Keep the description to what the tool does and when to use it; move reference material to resources or docs.