<!-- https://iposignal.xyz/docs/introduction.md -->

# IPOSignal API

US IPO data read from SEC filings and exchange calendars: deal terms, financial statements, valuation metrics, sentiment, and dated events such as lock-up expiries. Figures come from filings and market feeds, not from a language model, and a figure that cannot be sourced is left out.

The same data is available two ways:

- **HTTP**: `GET https://iposignal.xyz/api/agent/...`, described by an [OpenAPI document](https://iposignal.xyz/openapi.json).
- **MCP**: a Model Context Protocol server at `https://iposignal.xyz/api/oauth/mcp`, for Claude, ChatGPT, Cursor, VS Code and other MCP clients. They sign you in with your IPOSignal account.

## What you can get

| Data | HTTP endpoint | MCP tool | Price per call |
| --- | --- | --- | --- |
| Companies with financial statements | `/api/agent/companies` | `lookup_companies_with_financials` | Free |
| IPO snapshot by ticker | `/api/agent/ipo/by-symbol/{symbol}` | `get_ipo_snapshot` | $0.01 |
| IPO snapshot by id | `/api/agent/ipo/{id}` | `get_ipo_snapshot` | $0.01 |
| Financial statements | `/api/agent/financials/by-symbol/{symbol}` | `get_company_financials` | $0.01 |
| Live valuation metrics | `/api/agent/company-metrics` | `get_company_metrics` | $0.02 |
| IPO market sentiment | `/api/agent/ipo-sentiment` | `get_ipo_sentiment` | $0.01 |
| Social sentiment for one IPO | `/api/agent/social-sentiment` | `get_ipo_social_sentiment` | $0.01 |
| IPO events calendar | `/api/agent/ipo-events` | `get_ipo_events` | $0.02 |

Three more MCP tools are free and have no HTTP endpoint: `get_ipo_overview`, `get_ipo_pipeline` and `get_ipo_filings`. See [MCP server](https://iposignal.xyz/docs/mcp.md).

## Paying for a call

A paid call is covered by your account or by a payment. Either way, you are charged only when a call delivers a result: a not-found, a bad request or a server error costs nothing.

- **Your account.** Any account includes 250 calls a month, and a subscription 10,000. Use it with an API key, or by signing in from an MCP client.
- **x402.** No account: the endpoint answers `402` with a price, your client pays in USDC on Base, and the request is retried. Built for autonomous agents that hold a wallet.

Details are in [Authentication](https://iposignal.xyz/docs/authentication.md).

## Quickstart

The company directory is free and needs no key:

```bash
curl "https://iposignal.xyz/api/agent/companies?q=circle"
```

Then [create a key](https://iposignal.xyz/account) and call a paid endpoint:

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/ipo/by-symbol/CRCL"
```

[Getting started](https://iposignal.xyz/docs/getting-started.md) walks through both, and through connecting an MCP client.

## For coding agents

Paste this into Claude Code, Cursor or another coding agent to set a project up:

```text
Read https://iposignal.xyz/skill.md and https://iposignal.xyz/llms.txt.
Add an "IPOSignal API" section to AGENTS.md (or CLAUDE.md) that records: the base URL,
that the key is read from the IPOSIGNAL_API_KEY environment variable and never hard-coded,
which endpoint answers which question, and that only a 200 response is charged.
Then call https://iposignal.xyz/api/agent/companies?q=circle to confirm the setup works.
```

## Machine-readable

- [openapi.json](https://iposignal.xyz/openapi.json): the HTTP API as OpenAPI 3.1.
- [skill.md](https://iposignal.xyz/skill.md): how to call the API correctly, written for an agent.
- [llms.txt](https://iposignal.xyz/llms.txt): what the site is and where everything lives.
- [llms-full.txt](https://iposignal.xyz/llms-full.txt): every docs page in one file.
- Any docs page as Markdown: add `.md` to its URL.
- [Agent card](https://iposignal.xyz/.well-known/agent-card.json): the A2A descriptor.

---

<!-- https://iposignal.xyz/docs/getting-started.md -->

# Getting started

## 1. Make a free call

The company directory needs no key and no payment. It lists the companies we hold financial statements for.

```bash
curl "https://iposignal.xyz/api/agent/companies?q=circle"
```

```json
{
  "version": "1",
  "count": 1,
  "total": 1,
  "offset": 0,
  "limit": 200,
  "nextOffset": null,
  "data": [
    {
      "symbol": "CRCL",
      "company": "Circle Internet Group, Inc.",
      "cik": "0001876042",
      "latestPeriodEnd": "2026-09-30",
      "preIpoCount": 4,
      "postIpoCount": 8
    }
  ]
}
```

## 2. Create an API key

Sign in at [iposignal.xyz/account](https://iposignal.xyz/account) and create a key under **API access**. Any account can; there is nothing to pay.

- The key starts with `ips_live_` and is shown once. Only its hash is stored, so it cannot be shown again: copy it when you create it.
- A free account includes 250 calls a month, and a subscription 10,000.
- You can hold up to 5 active keys and revoke any of them from the same page.

Keep the key in an environment variable rather than in code:

```bash
export IPOSIGNAL_API_KEY="ips_live_YOUR_KEY"
```

## 3. Call a paid endpoint

```bash
curl -i -H "Authorization: Bearer $IPOSIGNAL_API_KEY" \
  "https://iposignal.xyz/api/agent/ipo-events?types=lockup_expiry"
```

A paid endpoint wraps its payload as `{ "version": "1", "data": ... }`. The response header `X-API-Quota-Remaining` says how many calls are left this month.

Only a delivered result counts against the quota. Asking for a ticker we do not cover returns `404` and costs nothing.

## 4. Connect an MCP client

An MCP client needs no key: it opens a browser and you sign in. In Claude Code:

```bash
claude mcp add --transport http iposignal https://iposignal.xyz/api/oauth/mcp
```

Then run `/mcp` in Claude Code and authenticate. Other clients, and connecting with a key instead, are covered in [MCP server](https://iposignal.xyz/docs/mcp.md).

## Next

- [API reference](https://iposignal.xyz/docs/api-reference.md): every endpoint, its parameters and an example response.
- [Authentication](https://iposignal.xyz/docs/authentication.md): keys and x402 in detail.
- [Quotas and errors](https://iposignal.xyz/docs/errors.md): what each status code means and whether to retry.

---

<!-- https://iposignal.xyz/docs/authentication.md -->

# Authentication

Free endpoints and free MCP tools need nothing. A paid call needs one of three things: an API key, a sign-in from an MCP client, or an x402 payment. The first two draw on the same monthly quota.

## API key

Create a key at [iposignal.xyz/account](https://iposignal.xyz/account). Send it on every paid request, in either header:

```http
Authorization: Bearer ips_live_YOUR_KEY
```

```http
X-API-Key: ips_live_YOUR_KEY
```

| Plan | Calls a month |
| --- | --- |
| Free account | 250 |
| Subscription | 10,000 |

- The quota belongs to the account, not to a key: all of an account's keys draw on one allowance.
- It resets on the 1st of each month, UTC.
- Only a delivered `200` is counted. The `X-API-Quota-Remaining` response header carries what is left.
- When the quota is spent, the call is not refused outright: it answers `402` with x402 terms, and the `error` field says the quota ran out. A client that can pay continues; one that cannot stops there until the reset.
- An unknown or revoked key answers `401`.
- A key is `ips_live_` followed by 43 characters. We store only its SHA-256 hash.

[Plans and prices](https://iposignal.xyz/pricing).

## Sign in from an MCP client (OAuth)

MCP clients such as Claude, ChatGPT, Cursor and VS Code connect to `https://iposignal.xyz/api/oauth/mcp` without a key. The client opens a browser, you sign in to IPOSignal and approve the connection, and from then on its calls to premium tools use your account's quota, exactly as an API key's would.

- You see a consent page naming the app and where your browser goes next. Approve only a connection you started.
- Connected apps are listed on your [account page](https://iposignal.xyz/account), where you can disconnect any of them.
- A connection is for the MCP server only. The HTTP endpoints take an API key.

For client developers: this is OAuth 2.1 with PKCE (S256) and dynamic client registration.

| Document | URL |
| --- | --- |
| Protected resource metadata (RFC 9728) | `https://iposignal.xyz/.well-known/oauth-protected-resource/api/oauth/mcp` |
| Authorization server metadata (RFC 8414) | `https://iposignal.xyz/.well-known/oauth-authorization-server` |

Access tokens last one hour. Refresh tokens are single-use: each refresh returns a new one, and presenting a used one ends the connection.

## x402: pay per call, no account

[x402](https://docs.x402.org) is an open protocol for paying for an HTTP request. It suits an autonomous agent that holds a wallet. Payment is in USDC on Base (network `eip155:8453`).

1. Call a paid endpoint with no key. It answers `402`. The JSON body, repeated base64-encoded in the `PAYMENT-REQUIRED` header, states the price, the asset, the network and the recipient.
2. Your x402 client signs a payment for that amount and retries with it in the `PAYMENT-SIGNATURE` header.
3. We verify the payment, look the data up, and settle only if there is a result to deliver. The response carries the settlement receipt in the `PAYMENT-RESPONSE` header.

A paid request that finds nothing returns `404` and the payment is never settled.

## On the MCP server

- **Sign-in:** point the client at `https://iposignal.xyz/api/oauth/mcp`. It answers `401` until the client has signed you in.
- **API key:** send the same `Authorization: Bearer` header when the client connects, to either MCP URL. Premium tools are then covered by the quota.
- **x402:** on `/api/mcp`, which needs no credential, an unpaid premium tool returns the payment terms as a tool result marked `isError`, with the terms in `structuredContent`. The client retries the call with the signed payment in `_meta["x402/payment"]`, and the paid result carries the receipt in `_meta["x402/payment-response"]`.

Setup for each client is in [MCP server](https://iposignal.xyz/docs/mcp.md).

---

<!-- https://iposignal.xyz/docs/mcp.md -->

# MCP server

The data as Model Context Protocol tools, over streamable HTTP. Server version 1.4.0. One server, two URLs:

| URL | Use it when | How a premium tool is covered |
| --- | --- | --- |
| `https://iposignal.xyz/api/oauth/mcp` | You use Claude, ChatGPT, Cursor, VS Code or another MCP client | You sign in; calls use your account's quota |
| `https://iposignal.xyz/api/mcp` | An agent pays per call, or you only want the free tools | x402 payment per call. No credential needed to connect |

Both serve the same tools, and both accept an API key as a bearer header. Premium tools cost the same as the matching HTTP endpoint. See [Authentication](https://iposignal.xyz/docs/authentication.md).

## Tools

| Tool | Price per call | What it returns |
| --- | --- | --- |
| `get_ipo_overview` | Free | The public facts of an IPO: company, ticker, CIK, exchange, listing date, shares offered, price range, final offer price when the deal has priced, and gross proceeds. Use it to identify a deal before buying the full profile with get_ipo_snapshot. Provide exactly one of companyId, symbol, or cik. |
| `lookup_companies_with_financials` | Free | Directory of companies we hold SEC iXBRL financial statements for, optionally filtered by ticker or company name. Returns ticker, company, CIK, latest reported period and pre/post-IPO period counts — use it to find which tickers get_company_financials can return. Paged: limit (default 200, max 500) and offset; the response carries total and nextOffset (null on the last page). |
| `get_ipo_snapshot` | $0.01 | Retrieve a complete IPO company profile — deal terms, pricing range, expected market cap, SEC registration and prospectus details, offering structure, lifecycle timeline, and IBKR indicative borrow fee rate when available. When available, includes AI-generated research with valuation models, competitor benchmarking, underwriter ratings, board analysis, and risk factors. Provide exactly one of companyId, symbol, or cik. |
| `get_ipo_sentiment` | $0.01 | Access IPOSignal's proprietary market sentiment score — a daily signal quantifying how well recent IPOs are being received by investors. Ranges from -100 (extreme bearish) to +100 (extreme bullish) with trend data for the last N days. Use it to identify favorable IPO windows, time investment entries, and assess overall market appetite for new listings. |
| `get_company_metrics` | $0.02 | Get live valuation metrics for any US-listed company (not just IPOs), computed from primary sources: SEC XBRL companyfacts TTM fundamentals (revenue, net income, EBITDA, debt, cash, shares) plus the latest market close. Returns multiples (P/E, P/S, EV/Revenue, EV/EBITDA), derivations (PEG, earnings/sales/EBITDA yields, net-debt/EBITDA), margins, and YoY growth — the same data IPOSignal's valuation pipeline uses for peer benchmarking, with the computation convention stated in the response. Provide exactly one of symbol (any SEC-mapped ticker) or companyName (resolves Nasdaq/NYSE listings). |
| `get_company_financials` | $0.01 | Retrieve full SEC iXBRL financial statements for a company we cover, pre- and post-IPO, with derived margins, growth, leverage and return ratios per period. Interim periods carry annualized figures alongside the reported ones. Provide a symbol. |
| `get_ipo_social_sentiment` | $0.01 | Get IPOSignal's X/Twitter social-sentiment reading for a specific IPO — an aggregate of how investors are discussing the stock on X, scored from -1 (bearish) to +1 (bullish) with a label, post tallies, and a one-line summary. The reading is taken once, before listing, and not refreshed: `ageDays` says how old it is and `reliable` is false when too few posts back it. Returns the aggregate signal only, not the underlying posts. Provide exactly one of companyId, symbol, or cik. |
| `get_ipo_pipeline` | Free | The US IPO pipeline: operating companies that have filed with the SEC but are not trading yet (status upcoming), or deals that were withdrawn or postponed. Each row has company, ticker when assigned, CIK, exchange, expected trading date when one is scheduled, the date of the latest status change, price range, shares offered, Nasdaq's deal size, and a link to the latest SEC filing. Status is the one the iposignal.xyz calendar shows, so SPACs and other vehicles are excluded. Use it to see what is coming to market or what was pulled; follow up with get_ipo_filings for one company's filing history or get_ipo_snapshot for the full deal profile. Arguments: status (upcoming, withdrawn or postponed; default upcoming), since as YYYY-MM-DD for withdrawn/postponed (default one year ago), limit (default 100, max 500). Upcoming deals sort by expected date, undated last. |
| `get_ipo_filings` | Free | One company's SEC filing timeline as we hold it, newest first: form type (S-1, S-1/A, F-1, F-1/A, EFFECT, 424B4, RW, 8-K, ...), filing date, and the link to the document on sec.gov. Use it to follow a registration from first S-1 through amendments to the final prospectus, or to confirm a withdrawal (RW). Covers the filings our SEC syncs collected for the company, not every filing it ever made. Provide exactly one of companyId, symbol, or cik. |
| `get_ipo_events` | $0.02 | Dated IPO events across all US IPOs in a window: lock-up expiries (with lock-up length), quiet-period expiries, and listings with offer price, first-day open and close, first-day pop and close return versus the offer, and lead managers. Use it to find upcoming lock-up expiries (supply overhang), quiet-period ends (analyst initiations) or how recent deals traded on day one. Arguments: from and to as YYYY-MM-DD (default today to today + 30 days, at most 366 days), types as a subset of lockup_expiry, quiet_period_expiry, listing (default all). |

The server also offers three prompts (`ipo_due_diligence`, `ipo_week_ahead`, `lockup_watch`) and one resource, `iposignal://guide`, which says which tool answers which question.

## Claude and ChatGPT

Add `https://iposignal.xyz/api/oauth/mcp` as a custom connector (in Claude: Settings, then Connectors, then Add custom connector). The app opens the IPOSignal sign-in page; approve the connection and the tools appear.

## Claude Code

```bash
claude mcp add --transport http iposignal https://iposignal.xyz/api/oauth/mcp
```

Then run `/mcp` and authenticate.

## Cursor

In `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` for every project. Cursor then offers to sign in:

```json
{
  "mcpServers": {
    "iposignal": {
      "url": "https://iposignal.xyz/api/oauth/mcp"
    }
  }
}
```

## VS Code

In `.vscode/mcp.json`. VS Code offers to sign in when the server starts:

```json
{
  "servers": {
    "iposignal": {
      "type": "http",
      "url": "https://iposignal.xyz/api/oauth/mcp"
    }
  }
}
```

## Clients that only speak stdio

Bridge through `mcp-remote`, which runs the sign-in for the client:

```json
{
  "mcpServers": {
    "iposignal": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://iposignal.xyz/api/oauth/mcp"
      ]
    }
  }
}
```

## With an API key instead of signing in

For a script, a CI job or a client that cannot open a browser, send a key as a header. In Claude Code:

```bash
claude mcp add --transport http iposignal https://iposignal.xyz/api/oauth/mcp \
  --header "Authorization: Bearer ips_live_YOUR_KEY"
```

In a JSON config, add the header beside the URL:

```json
{
  "mcpServers": {
    "iposignal": {
      "url": "https://iposignal.xyz/api/oauth/mcp",
      "headers": {
        "Authorization": "Bearer ips_live_YOUR_KEY"
      }
    }
  }
}
```

## Paying per call

An agent with a wallet connects to `https://iposignal.xyz/api/mcp` with no credential and pays for each premium call over x402. The flow is in [Authentication](https://iposignal.xyz/docs/authentication.md).

---

<!-- https://iposignal.xyz/docs/api-reference.md -->

# API reference

Base URL: `https://iposignal.xyz`. Every endpoint is a `GET` that returns JSON. This page is generated from the same definitions as the [OpenAPI document](https://iposignal.xyz/openapi.json).

Example responses are abridged. Fields may be `null` or absent when a filing does not state them, and new fields can be added at any time, so ignore fields you do not know.

Status codes shared by every endpoint are in [Quotas and errors](https://iposignal.xyz/docs/errors.md).

| Endpoint | Path | Price per call |
| --- | --- | --- |
| [Companies with financial statements](#companies-with-financial-statements) | `/api/agent/companies` | Free |
| [IPO snapshot by ticker](#ipo-snapshot-by-ticker) | `/api/agent/ipo/by-symbol/{symbol}` | $0.01 |
| [IPO snapshot by id](#ipo-snapshot-by-id) | `/api/agent/ipo/{id}` | $0.01 |
| [Financial statements](#financial-statements) | `/api/agent/financials/by-symbol/{symbol}` | $0.01 |
| [Live valuation metrics](#live-valuation-metrics) | `/api/agent/company-metrics` | $0.02 |
| [IPO market sentiment](#ipo-market-sentiment) | `/api/agent/ipo-sentiment` | $0.01 |
| [Social sentiment for one IPO](#social-sentiment-for-one-ipo) | `/api/agent/social-sentiment` | $0.01 |
| [IPO events calendar](#ipo-events-calendar) | `/api/agent/ipo-events` | $0.02 |

## Companies with financial statements

```http
GET /api/agent/companies
```

Directory of the companies we hold SEC iXBRL financial statements for. Use it to find which tickers the financials endpoint can return. Free, no key needed.

**Price:** free, no key needed. MCP tool: `lookup_companies_with_financials`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `q` | query | No | Filter by ticker or company name (case-insensitive substring). Omit to list every company. |
| `limit` | query | No | Page size, 1 to 500. Default 200. |
| `offset` | query | No | Rows to skip. Pass the previous response's nextOffset to fetch the next page. Default 0. |

```bash
curl "https://iposignal.xyz/api/agent/companies?q=circle"
```

Response:

```json
{
  "version": "1",
  "count": 1,
  "total": 1,
  "offset": 0,
  "limit": 200,
  "nextOffset": null,
  "data": [
    {
      "symbol": "CRCL",
      "company": "Circle Internet Group, Inc.",
      "cik": "0001876042",
      "latestPeriodEnd": "2026-09-30",
      "preIpoCount": 4,
      "postIpoCount": 8
    }
  ]
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `count` | integer | Rows in this page. |
| `total` | integer | Rows matching the query across all pages. |
| `offset` | integer | Rows skipped before this page. |
| `limit` | integer | Page size you asked for. |
| `nextOffset` | integer | Pass as offset to get the next page. Null on the last page. |
| `data` | array of objects | Companies we hold SEC financial statements for, sorted by ticker. |
| `data[].symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data[].company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data[].cik` | string | SEC Central Index Key: the registrant's permanent SEC identifier, as a 10-digit string with leading zeros, e.g. 0001876042. |
| `data[].latestPeriodEnd` | string | End date of the most recent period we hold, YYYY-MM-DD. Shows how current the statements are. |
| `data[].preIpoCount` | integer | How many periods (annual and interim) we hold from before the listing, read from the registration statement. 0 when we hold none. The financials endpoint returns them as preIpoPeriods. |
| `data[].postIpoCount` | integer | How many periods we hold from the 10-K, 10-Q and 20-F reports filed after the listing. 0 for a company that has not reported as a public company yet. Returned as postIpoPeriods. |



## IPO snapshot by ticker

```http
GET /api/agent/ipo/by-symbol/{symbol}
```

The full profile of one IPO: deal terms, price range and final offer price, market capitalisation, SEC registration and prospectus details, filing history, lifecycle timeline, borrow fee, and research where available.

**Price:** $0.01 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_ipo_snapshot`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `symbol` | path | Yes | US ticker symbol. Case-insensitive. Tickers get reassigned, so a response may carry a symbolNote. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/ipo/by-symbol/CRCL"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "company": "Circle Internet Group, Inc.",
    "cik": "0001876042",
    "symbol": "CRCL",
    "venue": "NYSE",
    "ipoDetails": {
      "date": "2025-06-05",
      "exchange": "NYSE",
      "shares": 34000000,
      "offerPrice": 31,
      "offerSize": 1054000000,
      "marketCap": 6898700000
    },
    "registration": {
      "form": "S-1/A",
      "filingDate": "2025-06-02",
      "effectivenessDate": null,
      "url": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/d737521ds1a.htm"
    },
    "filings": [
      {
        "formType": "S-1/A",
        "filingDate": "2025-06-02",
        "acceptedDate": null,
        "accessionNumber": "0001193125-25-132755",
        "indexUrl": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/",
        "documentUrl": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/d737521ds1a.htm"
      }
    ],
    "lifecycleEvents": [
      {
        "status": "priced",
        "date": "2025-06-05"
      }
    ],
    "borrowFee": {
      "feeRate": 0.2736,
      "asOfDate": "2026-05-22"
    }
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.cik` | string | SEC Central Index Key: the registrant's permanent SEC identifier, as a 10-digit string with leading zeros, e.g. 0001876042. |
| `data.symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.venue` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.updatedAt` | string | When any part of this record last changed, ISO 8601. |
| `data.ipoDetails` | object | Deal facts for the IPO. |
| `data.ipoDetails.date` | string | First trading day, YYYY-MM-DD. For a deal that has not listed, the scheduled date. |
| `data.ipoDetails.dateSource` | string | Where date comes from: observed-trading (a trade we observed on that day) or scheduled (an exchange calendar). |
| `data.ipoDetails.exchange` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.ipoDetails.shares` | number | Shares offered in the deal. Not shares outstanding. |
| `data.ipoDetails.priceRange` | string | The filed price range as text, low to high, USD per share, e.g. $16.00-$18.00. Null once the final price is known. |
| `data.ipoDetails.offerPrice` | number | Final offer price, USD per share. Null until the deal has priced. |
| `data.ipoDetails.marketCap` | number | What the company was worth at the offer, USD: economic shares outstanding right after the offering × offer price. Not the amount raised (see offerSize). |
| `data.ipoDetails.marketCapSource` | string | Where marketCap comes from: sec (share count from the filing), qra-prospectus (the final prospectus), scoop (IPOScoop), override (checked by hand). Null when unknown. |
| `data.ipoDetails.offerSize` | number | Gross proceeds, USD: shares offered × offer price. What the deal raised, not what the company is worth. |
| `data.ipoDetails.issuer` | string | Issuer line when it differs from company. Currently never set. |
| `data.registration` | object | The registration statement the deal was sold on: the latest S-1, F-1 or S-11 (or amendment) filed on or before the listing date. |
| `data.registration.form` | string | SEC form type: S-1, S-1/A, F-1, F-1/A, S-11 or S-11/A. |
| `data.registration.url` | string | The statement's main document on sec.gov. |
| `data.registration.filingDate` | string | Date the statement was filed, YYYY-MM-DD. |
| `data.registration.acceptedDate` | string | Time EDGAR accepted the filing, ISO 8601. |
| `data.registration.effectivenessDate` | string | Date the SEC declared the statement effective, YYYY-MM-DD. Currently always null: no source we read carries it. |
| `data.registration.status` | string | Registration status. Currently always null: no source we read carries it. |
| `data.filings` | array of objects | The company's SEC filings we track (registration statements, amendments, 424B prospectuses, delisting notices), oldest first. |
| `data.filings[].formType` | string | SEC form type, e.g. S-1, S-1/A, 424B4, EFFECT, RW, 25-NSE. |
| `data.filings[].filingDate` | string | Filing date, YYYY-MM-DD. |
| `data.filings[].acceptedDate` | string | Time EDGAR accepted the filing, ISO 8601. |
| `data.filings[].accessionNumber` | string | SEC accession number, the filing's unique id, e.g. 0001193125-25-132755. |
| `data.filings[].indexUrl` | string | The filing's folder on sec.gov, listing every document in it. |
| `data.filings[].documentUrl` | string | The filing's main document on sec.gov, when we resolved it. |
| `data.lifecycleEvents` | array of objects | The deal's dated status history, oldest first. |
| `data.lifecycleEvents[].status` | string | filed, expected, prelisting, priced, trading, postponed, withdrawn, halted, halt_resumed, delisted or acquired. |
| `data.lifecycleEvents[].date` | string | Date the status took effect, YYYY-MM-DD. |
| `data.borrowFee` | object | Latest indicative cost of borrowing the shares to sell short, from Interactive Brokers. Present once the stock trades and IBKR quotes it. |
| `data.borrowFee.feeRate` | number | Annual borrow fee in percent, IBKR's unit: 0.25 means 0.25% a year, 35 means 35% a year. |
| `data.borrowFee.asOfDate` | string | Date the rate was quoted, YYYY-MM-DD. |
| `data.research` | object | Research written by our AI pipeline from the prospectus: summary, competitors, board, risks and valuation work. Text, not filed figures: check a number against the filing before relying on it. Absent until the pipeline has run for the deal. |
| `data.research.summary` | string | Summary of the company and the deal. |
| `data.research.competitors` | array of strings | Named competitors. |
| `data.research.keyRisks` | array of strings | The main risks, one sentence each. |
| `data.research.useOfProceeds` | string | What the company says it will do with the money raised. |
| `data.research.boardOfDirectors` | array of objects | Directors named in the prospectus. |
| `data.research.boardOfDirectors[].name` | string | Director's name. |
| `data.research.boardOfDirectors[].role` | string | Role on the board, e.g. Chair, Independent Director. |
| `data.research.boardOfDirectors[].background` | string | Short background, when the prospectus gives one. |
| `data.research.isInvestmentVehicle` | boolean | True for a trust, fund, ETF or SPAC rather than an operating company. |
| `data.research.interestLevel` | string | Our read of how much attention the deal draws: High, Medium or Low. |
| `data.research.analystSector` | string | Sector we classify the company in. |
| `data.research.analystSubsector` | string | Subsector we classify the company in. |
| `data.research.sources` | array of strings | URLs the research cites. |
| `data.freedom24News` | object | News articles about the deal from Freedom24, when it covers the company. |
| `data.freedom24News.articles` | array of objects | Articles as Freedom24 publishes them: title, provider, date, URL and text. |
| `data.freedom24News.lastSyncedAt` | string | When we last fetched Freedom24's list for the company, ISO 8601. |
| `data.sec` | object | How the SEC classifies the company. |
| `data.sec.category` | string | SEC filer category, e.g. Non-accelerated filer, Emerging growth company. |
| `data.sec.description` | string | Industry from the company's SIC code, e.g. Services-Prepackaged Software. |
| `data.symbolNote` | object | Present only when the ticker you asked for has belonged to more than one company and the record served is not the current holder's. Absent on an ordinary lookup. |
| `data.symbolNote.requestedSymbol` | string | The ticker you asked for. |
| `data.symbolNote.servedCik` | string | CIK of the company whose record this response holds. |
| `data.symbolNote.currentHolderCik` | string | CIK of the company that holds the ticker today, when known. |
| `data.symbolNote.currentHolderName` | string | Name of the company that holds the ticker today, when known. |
| `data.symbolNote.reason` | string | Plain-language explanation of the mismatch. |

Errors besides the common ones: `404`. None is charged.

## IPO snapshot by id

```http
GET /api/agent/ipo/{id}
```

The same profile as the by-ticker endpoint, addressed by the IPOSignal company id that other responses return. Use it when a ticker is ambiguous or not yet assigned.

**Price:** $0.01 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_ipo_snapshot`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `id` | path | Yes | IPOSignal company id, 24 hexadecimal characters. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/ipo/6919e87469f7d961886f73f7"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "company": "Circle Internet Group, Inc.",
    "cik": "0001876042",
    "symbol": "CRCL",
    "venue": "NYSE",
    "ipoDetails": {
      "date": "2025-06-05",
      "exchange": "NYSE",
      "shares": 34000000,
      "offerPrice": 31,
      "offerSize": 1054000000,
      "marketCap": 6898700000
    },
    "registration": {
      "form": "S-1/A",
      "filingDate": "2025-06-02",
      "effectivenessDate": null,
      "url": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/d737521ds1a.htm"
    },
    "filings": [
      {
        "formType": "S-1/A",
        "filingDate": "2025-06-02",
        "acceptedDate": null,
        "accessionNumber": "0001193125-25-132755",
        "indexUrl": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/",
        "documentUrl": "https://www.sec.gov/Archives/edgar/data/1876042/000119312525132755/d737521ds1a.htm"
      }
    ],
    "lifecycleEvents": [
      {
        "status": "priced",
        "date": "2025-06-05"
      }
    ],
    "borrowFee": {
      "feeRate": 0.2736,
      "asOfDate": "2026-05-22"
    }
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.cik` | string | SEC Central Index Key: the registrant's permanent SEC identifier, as a 10-digit string with leading zeros, e.g. 0001876042. |
| `data.symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.venue` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.updatedAt` | string | When any part of this record last changed, ISO 8601. |
| `data.ipoDetails` | object | Deal facts for the IPO. |
| `data.ipoDetails.date` | string | First trading day, YYYY-MM-DD. For a deal that has not listed, the scheduled date. |
| `data.ipoDetails.dateSource` | string | Where date comes from: observed-trading (a trade we observed on that day) or scheduled (an exchange calendar). |
| `data.ipoDetails.exchange` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.ipoDetails.shares` | number | Shares offered in the deal. Not shares outstanding. |
| `data.ipoDetails.priceRange` | string | The filed price range as text, low to high, USD per share, e.g. $16.00-$18.00. Null once the final price is known. |
| `data.ipoDetails.offerPrice` | number | Final offer price, USD per share. Null until the deal has priced. |
| `data.ipoDetails.marketCap` | number | What the company was worth at the offer, USD: economic shares outstanding right after the offering × offer price. Not the amount raised (see offerSize). |
| `data.ipoDetails.marketCapSource` | string | Where marketCap comes from: sec (share count from the filing), qra-prospectus (the final prospectus), scoop (IPOScoop), override (checked by hand). Null when unknown. |
| `data.ipoDetails.offerSize` | number | Gross proceeds, USD: shares offered × offer price. What the deal raised, not what the company is worth. |
| `data.ipoDetails.issuer` | string | Issuer line when it differs from company. Currently never set. |
| `data.registration` | object | The registration statement the deal was sold on: the latest S-1, F-1 or S-11 (or amendment) filed on or before the listing date. |
| `data.registration.form` | string | SEC form type: S-1, S-1/A, F-1, F-1/A, S-11 or S-11/A. |
| `data.registration.url` | string | The statement's main document on sec.gov. |
| `data.registration.filingDate` | string | Date the statement was filed, YYYY-MM-DD. |
| `data.registration.acceptedDate` | string | Time EDGAR accepted the filing, ISO 8601. |
| `data.registration.effectivenessDate` | string | Date the SEC declared the statement effective, YYYY-MM-DD. Currently always null: no source we read carries it. |
| `data.registration.status` | string | Registration status. Currently always null: no source we read carries it. |
| `data.filings` | array of objects | The company's SEC filings we track (registration statements, amendments, 424B prospectuses, delisting notices), oldest first. |
| `data.filings[].formType` | string | SEC form type, e.g. S-1, S-1/A, 424B4, EFFECT, RW, 25-NSE. |
| `data.filings[].filingDate` | string | Filing date, YYYY-MM-DD. |
| `data.filings[].acceptedDate` | string | Time EDGAR accepted the filing, ISO 8601. |
| `data.filings[].accessionNumber` | string | SEC accession number, the filing's unique id, e.g. 0001193125-25-132755. |
| `data.filings[].indexUrl` | string | The filing's folder on sec.gov, listing every document in it. |
| `data.filings[].documentUrl` | string | The filing's main document on sec.gov, when we resolved it. |
| `data.lifecycleEvents` | array of objects | The deal's dated status history, oldest first. |
| `data.lifecycleEvents[].status` | string | filed, expected, prelisting, priced, trading, postponed, withdrawn, halted, halt_resumed, delisted or acquired. |
| `data.lifecycleEvents[].date` | string | Date the status took effect, YYYY-MM-DD. |
| `data.borrowFee` | object | Latest indicative cost of borrowing the shares to sell short, from Interactive Brokers. Present once the stock trades and IBKR quotes it. |
| `data.borrowFee.feeRate` | number | Annual borrow fee in percent, IBKR's unit: 0.25 means 0.25% a year, 35 means 35% a year. |
| `data.borrowFee.asOfDate` | string | Date the rate was quoted, YYYY-MM-DD. |
| `data.research` | object | Research written by our AI pipeline from the prospectus: summary, competitors, board, risks and valuation work. Text, not filed figures: check a number against the filing before relying on it. Absent until the pipeline has run for the deal. |
| `data.research.summary` | string | Summary of the company and the deal. |
| `data.research.competitors` | array of strings | Named competitors. |
| `data.research.keyRisks` | array of strings | The main risks, one sentence each. |
| `data.research.useOfProceeds` | string | What the company says it will do with the money raised. |
| `data.research.boardOfDirectors` | array of objects | Directors named in the prospectus. |
| `data.research.boardOfDirectors[].name` | string | Director's name. |
| `data.research.boardOfDirectors[].role` | string | Role on the board, e.g. Chair, Independent Director. |
| `data.research.boardOfDirectors[].background` | string | Short background, when the prospectus gives one. |
| `data.research.isInvestmentVehicle` | boolean | True for a trust, fund, ETF or SPAC rather than an operating company. |
| `data.research.interestLevel` | string | Our read of how much attention the deal draws: High, Medium or Low. |
| `data.research.analystSector` | string | Sector we classify the company in. |
| `data.research.analystSubsector` | string | Subsector we classify the company in. |
| `data.research.sources` | array of strings | URLs the research cites. |
| `data.freedom24News` | object | News articles about the deal from Freedom24, when it covers the company. |
| `data.freedom24News.articles` | array of objects | Articles as Freedom24 publishes them: title, provider, date, URL and text. |
| `data.freedom24News.lastSyncedAt` | string | When we last fetched Freedom24's list for the company, ISO 8601. |
| `data.sec` | object | How the SEC classifies the company. |
| `data.sec.category` | string | SEC filer category, e.g. Non-accelerated filer, Emerging growth company. |
| `data.sec.description` | string | Industry from the company's SIC code, e.g. Services-Prepackaged Software. |
| `data.symbolNote` | object | Present only when the ticker you asked for has belonged to more than one company and the record served is not the current holder's. Absent on an ordinary lookup. |
| `data.symbolNote.requestedSymbol` | string | The ticker you asked for. |
| `data.symbolNote.servedCik` | string | CIK of the company whose record this response holds. |
| `data.symbolNote.currentHolderCik` | string | CIK of the company that holds the ticker today, when known. |
| `data.symbolNote.currentHolderName` | string | Name of the company that holds the ticker today, when known. |
| `data.symbolNote.reason` | string | Plain-language explanation of the mismatch. |

Errors besides the common ones: `404`. None is charged.

## Financial statements

```http
GET /api/agent/financials/by-symbol/{symbol}
```

SEC iXBRL income statement, balance sheet and cash-flow line items for a company we cover, before and after its IPO, with margins, growth, leverage and return ratios per period. Interim periods carry annualised figures beside the reported ones.

**Price:** $0.01 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_company_financials`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `symbol` | path | Yes | US ticker symbol. Case-insensitive. Tickers get reassigned, so a response may carry a symbolNote. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/financials/by-symbol/CRCL"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "company": "Circle Internet Group, Inc.",
    "symbol": "CRCL",
    "cik": "0001876042",
    "sec": {
      "periodicFinancials": {
        "fetchedAt": "2026-06-23T11:23:08.986Z"
      }
    }
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.cik` | string | SEC Central Index Key: the registrant's permanent SEC identifier, as a 10-digit string with leading zeros, e.g. 0001876042. |
| `data.fetchedAt` | string | When we last read the statements from SEC, ISO 8601. |
| `data.preIpoPeriods` | array of objects | Periods reported in the registration statement, before the listing. |
| `data.preIpoPeriods[].periodEndDate` | string | Last day of the period, YYYY-MM-DD. |
| `data.preIpoPeriods[].periodStartDate` | string | First day of the period, YYYY-MM-DD. Absent for a balance-sheet-only period. |
| `data.preIpoPeriods[].periodType` | string | Annual, Quarterly, Semi-Annual, Nine Months Ended, Instant (a balance-sheet date with no income or cash-flow figures), or N-Day Period for any other length, e.g. 45-Day Period. |
| `data.preIpoPeriods[].durationMonths` | integer | Length of the period in whole months: 12 for a year, 3 for a quarter, 6 or 9 for year-to-date, 0 for an Instant. |
| `data.preIpoPeriods[].currency` | string | ISO 4217 currency the figures in metrics are in, e.g. USD, CNY. USD when absent. |
| `data.preIpoPeriods[].fxToUsd` | number | USD per one unit of currency. Multiply a figure by it to get USD. Absent for USD. |
| `data.preIpoPeriods[].fxRateDate` | string | Date the fxToUsd rate was taken, YYYY-MM-DD: the IPO date for pre-IPO periods, the period end for later ones. |
| `data.preIpoPeriods[].metrics` | map of name → number | Statement line items as filed, keyed by line name, in currency, whole units (not thousands). Only the lines the filing reports are present. Every key is listed under Line items. |
| `data.preIpoPeriods[].annualizedMetrics` | map of name → number | Interim periods only: the flow items in metrics scaled to twelve months, so a quarter compares with a year. Balance-sheet items are copied unchanged. |
| `data.preIpoPeriods[].annualizationMethod` | string | How annualizedMetrics was made: ttm (last full year + this year to date − last year to date) or scaled (× 12 ÷ durationMonths). |
| `data.preIpoPeriods[].derived` | map of name → number | Ratios computed from metrics, in percent: grossMarginPct, operatingMarginPct, netMarginPct, fcfMarginPct, revenueGrowthPct, debtToAssetsPct, equityRatioPct, returnOnEquityPct, returnOnAssetsPct, cashToAssetsPct. A ratio is absent when an input is missing. |
| `data.postIpoPeriods` | array of objects | Periods from the 10-K, 10-Q and 20-F reports filed after the listing. |
| `data.postIpoPeriods[].periodEndDate` | string | Last day of the period, YYYY-MM-DD. |
| `data.postIpoPeriods[].periodStartDate` | string | First day of the period, YYYY-MM-DD. Absent for a balance-sheet-only period. |
| `data.postIpoPeriods[].periodType` | string | Annual, Quarterly, Semi-Annual, Nine Months Ended, Instant (a balance-sheet date with no income or cash-flow figures), or N-Day Period for any other length, e.g. 45-Day Period. |
| `data.postIpoPeriods[].durationMonths` | integer | Length of the period in whole months: 12 for a year, 3 for a quarter, 6 or 9 for year-to-date, 0 for an Instant. |
| `data.postIpoPeriods[].currency` | string | ISO 4217 currency the figures in metrics are in, e.g. USD, CNY. USD when absent. |
| `data.postIpoPeriods[].fxToUsd` | number | USD per one unit of currency. Multiply a figure by it to get USD. Absent for USD. |
| `data.postIpoPeriods[].fxRateDate` | string | Date the fxToUsd rate was taken, YYYY-MM-DD: the IPO date for pre-IPO periods, the period end for later ones. |
| `data.postIpoPeriods[].metrics` | map of name → number | Statement line items as filed, keyed by line name, in currency, whole units (not thousands). Only the lines the filing reports are present. Every key is listed under Line items. |
| `data.postIpoPeriods[].annualizedMetrics` | map of name → number | Interim periods only: the flow items in metrics scaled to twelve months, so a quarter compares with a year. Balance-sheet items are copied unchanged. |
| `data.postIpoPeriods[].annualizationMethod` | string | How annualizedMetrics was made: ttm (last full year + this year to date − last year to date) or scaled (× 12 ÷ durationMonths). |
| `data.postIpoPeriods[].derived` | map of name → number | Ratios computed from metrics, in percent: grossMarginPct, operatingMarginPct, netMarginPct, fcfMarginPct, revenueGrowthPct, debtToAssetsPct, equityRatioPct, returnOnEquityPct, returnOnAssetsPct, cashToAssetsPct. A ratio is absent when an input is missing. |
| `data.symbolNote` | object | Present only when the ticker you asked for has belonged to more than one company and the record served is not the current holder's. Absent on an ordinary lookup. |
| `data.symbolNote.requestedSymbol` | string | The ticker you asked for. |
| `data.symbolNote.servedCik` | string | CIK of the company whose record this response holds. |
| `data.symbolNote.currentHolderCik` | string | CIK of the company that holds the ticker today, when known. |
| `data.symbolNote.currentHolderName` | string | Name of the company that holds the ticker today, when known. |
| `data.symbolNote.reason` | string | Plain-language explanation of the mismatch. |

### Line items

The keys `metrics` and `annualizedMetrics` can carry. A period has only the lines its filing reports. Each is read from the XBRL concepts listed.

| Key | Statement | XBRL concepts |
| --- | --- | --- |
| `revenue` | Income statement | us-gaap:Revenues, us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax, us-gaap:SalesRevenueNet, us-gaap:RevenueFromContractWithCustomerIncludingAssessedTax, ifrs-full:Revenue, ifrs-full:RevenueFromContractsWithCustomers |
| `costOfRevenue` | Income statement | us-gaap:CostOfRevenue, us-gaap:CostOfGoodsAndServicesSold, us-gaap:CostOfGoodsSold, ifrs-full:CostOfSales |
| `grossProfit` | Income statement | us-gaap:GrossProfit, ifrs-full:GrossProfit |
| `researchAndDevelopment` | Income statement | us-gaap:ResearchAndDevelopmentExpense, us-gaap:ResearchAndDevelopmentExpenseExcludingAcquiredInProcessCost, ifrs-full:ResearchAndDevelopmentExpense |
| `sellingGeneralAndAdministrative` | Income statement | us-gaap:SellingGeneralAndAdministrativeExpense, us-gaap:GeneralAndAdministrativeExpense |
| `sellingAndMarketing` | Income statement | us-gaap:SellingAndMarketingExpense, us-gaap:MarketingAndAdvertisingExpense, us-gaap:MarketingExpense |
| `depreciationAndAmortization` | Income statement | us-gaap:DepreciationDepletionAndAmortization, us-gaap:DepreciationAmortizationAndAccretionNet, us-gaap:DepreciationAndAmortization, ifrs-full:DepreciationAndAmortisationExpense |
| `operatingExpenses` | Income statement | us-gaap:OperatingExpenses, ifrs-full:OperatingExpense |
| `costsAndExpenses` | Income statement | us-gaap:CostsAndExpenses, us-gaap:OperatingCostsAndExpenses, us-gaap:BenefitsLossesAndExpenses |
| `operatingIncome` | Income statement | us-gaap:OperatingIncomeLoss, ifrs-full:ProfitLossFromOperatingActivities |
| `interestExpense` | Income statement | us-gaap:InterestExpense, us-gaap:InterestExpenseNonoperating, us-gaap:InterestIncomeExpenseNet, ifrs-full:InterestExpense, ifrs-full:FinanceCosts |
| `interestIncome` | Income statement | us-gaap:InvestmentIncomeInterest, us-gaap:InterestAndDividendIncomeOperating, us-gaap:InterestIncomeOperating |
| `otherIncomeExpenseNet` | Income statement | us-gaap:OtherNonoperatingIncomeExpense, us-gaap:NonoperatingIncomeExpense |
| `pretaxIncome` | Income statement | us-gaap:IncomeLossFromContinuingOperationsBeforeIncomeTaxesMinorityInterestAndIncomeLossFromEquityMethodInvestments, us-gaap:IncomeLossFromContinuingOperationsBeforeIncomeTaxesExtraordinaryItemsNoncontrollingInterest, ifrs-full:ProfitLossBeforeTax |
| `incomeTaxExpense` | Income statement | us-gaap:IncomeTaxExpenseBenefit, ifrs-full:IncomeTaxExpenseContinuingOperations |
| `netIncome` | Income statement | us-gaap:NetIncomeLoss, us-gaap:ProfitLoss, us-gaap:IncomeLossFromContinuingOperations, ifrs-full:ProfitLoss |
| `netIncomeToNoncontrollingInterest` | Income statement | us-gaap:NetIncomeLossAttributableToNoncontrollingInterest |
| `netIncomeAvailableToCommon` | Income statement | us-gaap:NetIncomeLossAvailableToCommonStockholdersBasic |
| `comprehensiveIncome` | Income statement | us-gaap:ComprehensiveIncomeNetOfTax, ifrs-full:ComprehensiveIncome |
| `stockBasedCompensation` | Income statement | us-gaap:ShareBasedCompensation, us-gaap:AllocatedShareBasedCompensationExpense |
| `operatingCashFlow` | Cash flow | us-gaap:NetCashProvidedByUsedInOperatingActivities, us-gaap:NetCashProvidedByUsedInOperatingActivitiesContinuingOperations, ifrs-full:CashFlowsFromUsedInOperatingActivities |
| `investingCashFlow` | Cash flow | us-gaap:NetCashProvidedByUsedInInvestingActivities, us-gaap:NetCashProvidedByUsedInInvestingActivitiesContinuingOperations |
| `financingCashFlow` | Cash flow | us-gaap:NetCashProvidedByUsedInFinancingActivities, us-gaap:NetCashProvidedByUsedInFinancingActivitiesContinuingOperations |
| `capitalExpenditures` | Cash flow | us-gaap:PaymentsToAcquirePropertyPlantAndEquipment, us-gaap:PaymentsToAcquireProductiveAssets, ifrs-full:PurchaseOfPropertyPlantAndEquipmentClassifiedAsInvestingActivities |
| `dividendsPaid` | Cash flow | us-gaap:PaymentsOfDividendsCommonStock, us-gaap:PaymentsOfDividends |
| `repurchaseOfStock` | Cash flow | us-gaap:PaymentsForRepurchaseOfCommonStock |
| `proceedsFromStockIssuance` | Cash flow | us-gaap:ProceedsFromIssuanceOfCommonStock, us-gaap:ProceedsFromIssuanceInitialPublicOffering, us-gaap:ProceedsFromIssuanceOfCommonStockNetOfIssuanceCosts |
| `netChangeInCash` | Cash flow | us-gaap:CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalentsPeriodIncreaseDecreaseIncludingExchangeRateEffect, us-gaap:CashAndCashEquivalentsPeriodIncreaseDecrease |
| `proceedsFromDebt` | Cash flow | us-gaap:ProceedsFromIssuanceOfLongTermDebt, us-gaap:ProceedsFromIssuanceOfDebt |
| `repaymentOfDebt` | Cash flow | us-gaap:RepaymentsOfLongTermDebt, us-gaap:RepaymentsOfDebt |
| `totalAssets` | Balance sheet | us-gaap:Assets, ifrs-full:Assets |
| `currentAssets` | Balance sheet | us-gaap:AssetsCurrent, ifrs-full:CurrentAssets |
| `cashAndCashEquivalents` | Balance sheet | us-gaap:CashAndCashEquivalentsAtCarryingValue, us-gaap:CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents, us-gaap:Cash, ifrs-full:CashAndCashEquivalents |
| `shortTermInvestments` | Balance sheet | us-gaap:ShortTermInvestments, us-gaap:MarketableSecuritiesCurrent, us-gaap:AvailableForSaleSecuritiesCurrent |
| `accountsReceivable` | Balance sheet | us-gaap:AccountsReceivableNetCurrent, us-gaap:ReceivablesNetCurrent |
| `prepaidExpenses` | Balance sheet | us-gaap:PrepaidExpenseAndOtherAssetsCurrent, us-gaap:PrepaidExpenseCurrent |
| `inventory` | Balance sheet | us-gaap:InventoryNet, ifrs-full:Inventories |
| `propertyPlantEquipment` | Balance sheet | us-gaap:PropertyPlantAndEquipmentNet, ifrs-full:PropertyPlantAndEquipment |
| `operatingLeaseRightOfUseAsset` | Balance sheet | us-gaap:OperatingLeaseRightOfUseAsset |
| `goodwill` | Balance sheet | us-gaap:Goodwill, ifrs-full:Goodwill |
| `intangibleAssets` | Balance sheet | us-gaap:IntangibleAssetsNetExcludingGoodwill, us-gaap:FiniteLivedIntangibleAssetsNet |
| `otherAssetsNoncurrent` | Balance sheet | us-gaap:OtherAssetsNoncurrent |
| `totalLiabilities` | Balance sheet | us-gaap:Liabilities, ifrs-full:Liabilities |
| `currentLiabilities` | Balance sheet | us-gaap:LiabilitiesCurrent, ifrs-full:CurrentLiabilities |
| `accountsPayable` | Balance sheet | us-gaap:AccountsPayableCurrent, us-gaap:AccountsPayableAndAccruedLiabilitiesCurrent |
| `accruedLiabilities` | Balance sheet | us-gaap:AccruedLiabilitiesCurrent |
| `deferredRevenue` | Balance sheet | us-gaap:ContractWithCustomerLiabilityCurrent, us-gaap:ContractWithCustomerLiability, us-gaap:DeferredRevenueCurrent |
| `remainingPerformanceObligations` | Balance sheet | us-gaap:RevenueRemainingPerformanceObligation |
| `shortTermDebt` | Balance sheet | us-gaap:LongTermDebtCurrent, us-gaap:DebtCurrent, us-gaap:ShortTermBorrowings |
| `longTermDebt` | Balance sheet | us-gaap:LongTermDebtNoncurrent, us-gaap:LongTermDebt, us-gaap:LongTermDebtAndCapitalLeaseObligations |
| `operatingLeaseLiabilityCurrent` | Balance sheet | us-gaap:OperatingLeaseLiabilityCurrent |
| `operatingLeaseLiability` | Balance sheet | us-gaap:OperatingLeaseLiabilityNoncurrent, us-gaap:OperatingLeaseLiability |
| `otherLiabilitiesNoncurrent` | Balance sheet | us-gaap:OtherLiabilitiesNoncurrent |
| `equityItemsBetweenLiabilitiesAndEquity` | Balance sheet | us-gaap:TemporaryEquityCarryingAmountAttributableToParent, us-gaap:TemporaryEquityCarryingAmountIncludingPortionAttributableToNoncontrollingInterests, us-gaap:RedeemableNoncontrollingInterestEquityCarryingAmount, us-gaap:RedeemableNoncontrollingInterestEquityPreferredCarryingAmount, us-gaap:RedeemableNoncontrollingInterestEquityCommonCarryingAmount |
| `totalEquity` | Balance sheet | us-gaap:StockholdersEquityIncludingPortionAttributableToNoncontrollingInterest, us-gaap:StockholdersEquity, ifrs-full:Equity, ifrs-full:EquityAttributableToOwnersOfParent |
| `commonStockValue` | Balance sheet | us-gaap:CommonStockValue |
| `preferredStockValue` | Balance sheet | us-gaap:PreferredStockValue, us-gaap:PreferredStockValueOutstanding |
| `additionalPaidInCapital` | Balance sheet | us-gaap:AdditionalPaidInCapital, us-gaap:AdditionalPaidInCapitalCommonStock, ifrs-full:SharePremium |
| `retainedEarnings` | Balance sheet | us-gaap:RetainedEarningsAccumulatedDeficit, ifrs-full:RetainedEarnings |
| `treasuryStockValue` | Balance sheet | us-gaap:TreasuryStockValue, us-gaap:TreasuryStockCommonValue |
| `accumulatedOci` | Balance sheet | us-gaap:AccumulatedOtherComprehensiveIncomeLossNetOfTax |
| `noncontrollingInterest` | Balance sheet | us-gaap:MinorityInterest |

### Ratios

The keys `derived` can carry, in percent, computed from the same period's `metrics`.

| Key | How it is computed |
| --- | --- |
| `grossMarginPct` | grossProfit ÷ revenue |
| `operatingMarginPct` | operatingIncome ÷ revenue |
| `netMarginPct` | netIncome ÷ revenue |
| `fcfMarginPct` | (operatingCashFlow − capitalExpenditures) ÷ revenue |
| `revenueGrowthPct` | revenue against the same-length period about one period earlier |
| `debtToAssetsPct` | totalLiabilities ÷ totalAssets |
| `equityRatioPct` | totalEquity ÷ totalAssets |
| `returnOnEquityPct` | netIncome ÷ totalEquity |
| `returnOnAssetsPct` | netIncome ÷ totalAssets |
| `cashToAssetsPct` | cashAndCashEquivalents ÷ totalAssets |

Errors besides the common ones: `404`. None is charged.

## Live valuation metrics

```http
GET /api/agent/company-metrics
```

Valuation metrics for any US-listed company, not only IPOs: trailing-twelve-month fundamentals from SEC XBRL company facts and the latest market close, giving P/E, P/S, EV/Revenue, EV/EBITDA, PEG, yields, net debt to EBITDA, margins and year-on-year growth. The response states how each figure is computed. Provide exactly one of symbol or name.

**Price:** $0.02 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_company_metrics`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `symbol` | query | No | US ticker. Any ticker the SEC maps to a registrant. |
| `name` | query | No | Company name, for when the ticker is unknown. Resolves Nasdaq and NYSE listings only. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/company-metrics?symbol=CRCL"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "listing": {
      "ticker": "CRCL",
      "name": "Circle Internet Group, Inc.",
      "exchange": "NYSE",
      "cik": 1876042
    },
    "priceClose": 64.08,
    "fundamentalsTtm": {
      "revenue": 3030568000,
      "netIncome": 462914000,
      "ebitda": 459250000,
      "freeCashFlow": 740687000,
      "totalDebt": null,
      "cash": 1699951000,
      "sharesOutstanding": 256553104
    },
    "valuation": {
      "marketCap": 16438640139,
      "enterpriseValue": 14738689139,
      "peRatio": 35.51,
      "priceToSalesRatio": 5.42,
      "evRevenueMultiple": 4.86,
      "evEbitda": 32.09,
      "pegRatio": null
    }
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.listing` | object | The company the query resolved to. |
| `data.listing.ticker` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.listing.name` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.listing.exchange` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.listing.cik` | integer | SEC Central Index Key as a number, without leading zeros, e.g. 1876042. |
| `data.priceClose` | number | Latest daily closing price, USD per share. |
| `data.fundamentalsTtm` | object | Trailing-twelve-month figures from SEC XBRL company facts, USD: the last full year + this year to date − last year to date. |
| `data.fundamentalsTtm.revenue` | number | Revenue, USD. |
| `data.fundamentalsTtm.netIncome` | number | Net income, USD. Negative for a loss. |
| `data.fundamentalsTtm.ebitda` | number | Operating income + depreciation and amortization, USD. |
| `data.fundamentalsTtm.freeCashFlow` | number | Operating cash flow − capital expenditures, USD. |
| `data.fundamentalsTtm.totalDebt` | number | Debt at the latest balance sheet, USD: the combined debt figure when filed, else long-term debt + its current portion + short-term borrowings. |
| `data.fundamentalsTtm.cash` | number | Cash and cash equivalents at the latest balance sheet, USD. |
| `data.fundamentalsTtm.sharesOutstanding` | number | Shares outstanding used for marketCap. See sharesSource for which count it is. |
| `data.fundamentalsTtm.sharesSource` | object | Which share count sharesOutstanding is. |
| `data.fundamentalsTtm.sharesSource.method` | string | dei-total (the total on a 10-K or 10-Q cover), cover-per-class (the sum of the share classes on the cover) or weighted-average-basic (the EPS denominator, used only when no cover count exists). |
| `data.fundamentalsTtm.sharesSource.asOf` | string | Date the count is as of, YYYY-MM-DD. |
| `data.fundamentalsTtm.sharesSource.accession` | string | Accession number of the filing the count was read from. |
| `data.fundamentalsTtm.sharesSource.classCount` | integer | cover-per-class only: how many share classes were summed. |
| `data.valuation` | object | Multiples at priceClose. A multiple is null when its denominator is missing or not positive. |
| `data.valuation.marketCap` | number | priceClose × sharesOutstanding, USD. |
| `data.valuation.enterpriseValue` | number | marketCap + totalDebt − cash, USD. Null unless both debt and cash are reported: an unreported figure is unknown, not 0. |
| `data.valuation.peRatio` | number | Price to earnings: marketCap ÷ TTM net income. Null when net income is zero or negative. |
| `data.valuation.priceToSalesRatio` | number | marketCap ÷ TTM revenue. |
| `data.valuation.evRevenueMultiple` | number | enterpriseValue ÷ TTM revenue. |
| `data.valuation.evEbitda` | number | enterpriseValue ÷ TTM EBITDA. Null when EBITDA is zero or negative. |
| `data.valuation.pegRatio` | number | peRatio ÷ netIncomeGrowthPct. Null unless both are positive. |
| `data.valuation.earningsYieldPct` | number | TTM net income ÷ marketCap, percent. |
| `data.valuation.salesYieldPct` | number | TTM revenue ÷ marketCap, percent. |
| `data.valuation.revenueEvYieldPct` | number | TTM revenue ÷ enterpriseValue, percent. |
| `data.valuation.ebitdaEvYieldPct` | number | TTM EBITDA ÷ enterpriseValue, percent. |
| `data.valuation.freeCashFlowEvYieldPct` | number | TTM free cash flow ÷ enterpriseValue, percent. Negative for a company burning cash. |
| `data.valuation.netDebtToEbitda` | number | (totalDebt − cash) ÷ TTM EBITDA. Negative when cash exceeds debt; null unless both are reported. |
| `data.profile` | object | Margins over the trailing twelve months and growth over the last fiscal year, percent. |
| `data.profile.grossMarginPct` | number | Gross profit ÷ revenue. |
| `data.profile.ebitdaMarginPct` | number | EBITDA ÷ revenue. |
| `data.profile.freeCashFlowMarginPct` | number | Free cash flow ÷ revenue. |
| `data.profile.revenueGrowthPct` | number | Revenue in the latest fiscal year against the year before. Null when the earlier year is zero or negative. |
| `data.profile.operatingIncomeGrowthPct` | number | Operating income in the latest fiscal year against the year before. Null when the earlier year is zero or negative. |
| `data.profile.netIncomeGrowthPct` | number | Net income in the latest fiscal year against the year before. Null when the earlier year is zero or negative. |
| `data.sources` | object | Where each input came from, in words. |
| `data.sources.fundamentals` | string | Source and method of fundamentalsTtm. |
| `data.sources.price` | string | Source of priceClose. |
| `data.sources.convention` | string | How EBITDA, enterprise value and PEG are defined. |
| `data.sources.shares` | string | Which share count was used, from which filing, and what it assumes. |
| `data.unavailable` | object | Present instead of the figures when the company resolved but no market cap can be struck. |
| `data.unavailable.reason` | string | no-price (no recent close), no-share-count (no share count filed yet) or no-sec-facts (SEC company facts unreadable). |
| `data.unavailable.detail` | string | Plain-language explanation. |

Errors besides the common ones: `400`, `404`. None is charged.

## IPO market sentiment

```http
GET /api/agent/ipo-sentiment
```

The IPOSignal sentiment score: a daily reading from -100 to +100 of how recent IPOs are being received, with its trend over the last N days.

**Price:** $0.01 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_ipo_sentiment`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `days` | query | No | Trend window in days. Values outside 1 to 90 are clamped. Default 14. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/ipo-sentiment?days=30"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "current": {
      "date": "2026-09-21",
      "score": 62,
      "direction": "bullish",
      "strength": "moderate",
      "sampleSize": 18,
      "reliable": true,
      "computedAt": "2026-09-21T06:00:00.000Z"
    },
    "trend": [
      {
        "date": "2026-09-21",
        "score": 62,
        "direction": "bullish",
        "strength": "moderate",
        "sampleSize": 18,
        "reliable": true,
        "computedAt": "2026-09-21T06:00:00.000Z"
      }
    ],
    "summary": "IPO market sentiment is moderately bullish and stable. Score: 62/100 based on 18 recent IPOs."
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.current` | object | The latest daily score. |
| `data.current.date` | string | Day the score is for, YYYY-MM-DD. |
| `data.current.score` | number | -100 (extremely bearish) to +100 (extremely bullish). Built from how recent IPOs traded in their first 30 days: the level over the last 30 days and its change against the last 60. |
| `data.current.direction` | string | bullish, bearish or neutral. |
| `data.current.strength` | string | weak, moderate or strong. |
| `data.current.sampleSize` | integer | How many recent IPOs the score is computed from. |
| `data.current.reliable` | boolean | False when sampleSize is below 5: too few IPOs to trust the score. |
| `data.current.computedAt` | string | When the score was computed, ISO 8601. |
| `data.trend` | array of objects | Daily scores for the window you asked for, newest first. |
| `data.trend[].date` | string | Day the score is for, YYYY-MM-DD. |
| `data.trend[].score` | number | -100 (extremely bearish) to +100 (extremely bullish). Built from how recent IPOs traded in their first 30 days: the level over the last 30 days and its change against the last 60. |
| `data.trend[].direction` | string | bullish, bearish or neutral. |
| `data.trend[].strength` | string | weak, moderate or strong. |
| `data.trend[].sampleSize` | integer | How many recent IPOs the score is computed from. |
| `data.trend[].reliable` | boolean | False when sampleSize is below 5: too few IPOs to trust the score. |
| `data.trend[].computedAt` | string | When the score was computed, ISO 8601. |
| `data.summary` | string | One sentence: the level, the direction over the last 7 days, and the sample size. |

Errors besides the common ones: `404`. None is charged.

## Social sentiment for one IPO

```http
GET /api/agent/social-sentiment
```

The aggregate X/Twitter reading for one IPO: a score from -1 to +1, a label, post tallies and a one-line summary. Taken once before listing and not refreshed: ageDays says how old it is, and reliable is false when too few posts back it. The posts themselves are not returned. Provide exactly one of symbol, cik or id.

**Price:** $0.01 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_ipo_social_sentiment`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `symbol` | query | No | US ticker. |
| `cik` | query | No | SEC Central Index Key, with or without leading zeros. |
| `id` | query | No | IPOSignal company id. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/social-sentiment?symbol=CRCL"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "company": "Circle Internet Group, Inc.",
    "symbol": "CRCL",
    "score": 0.41,
    "label": "bullish",
    "postCount": 128,
    "positiveHits": 71,
    "negativeHits": 22,
    "summary": "Discussion skews bullish on listing-day liquidity.",
    "analyzedAt": "2026-09-21T09:12:00.000Z",
    "ageDays": 2,
    "reliable": true
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.score` | number | -1 (all posts bearish) to +1 (all posts bullish), across the posts read. |
| `data.label` | string | Bullish, Neutral or Bearish. |
| `data.postCount` | integer | How many posts on X the reading is based on. |
| `data.positiveHits` | integer | Posts scored positive. |
| `data.negativeHits` | integer | Posts scored negative. |
| `data.summary` | string | One-line summary of the conversation. |
| `data.analyzedAt` | string | When the posts were read, ISO 8601. |
| `data.ageDays` | integer | Whole days since analyzedAt. Readings are taken in the days before listing and not refreshed, so an old reading is the pre-IPO mood. |
| `data.reliable` | boolean | False when too few posts back the reading: one post can set the label. |
| `data.symbolNote` | object | Present only when the ticker you asked for has belonged to more than one company and the record served is not the current holder's. Absent on an ordinary lookup. |
| `data.symbolNote.requestedSymbol` | string | The ticker you asked for. |
| `data.symbolNote.servedCik` | string | CIK of the company whose record this response holds. |
| `data.symbolNote.currentHolderCik` | string | CIK of the company that holds the ticker today, when known. |
| `data.symbolNote.currentHolderName` | string | Name of the company that holds the ticker today, when known. |
| `data.symbolNote.reason` | string | Plain-language explanation of the mismatch. |

Errors besides the common ones: `400`, `404`. None is charged.

## IPO events calendar

```http
GET /api/agent/ipo-events
```

Dated events across all US IPOs in a window: lock-up expiries with the lock-up length, quiet-period expiries, and listings with offer price, first-day open and close, first-day returns and lead managers. A window with no events is returned without charge.

**Price:** $0.02 per delivered call over x402, or one call from an API key's quota. MCP tool: `get_ipo_events`.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `from` | query | No | Window start, YYYY-MM-DD. Defaults to today. |
| `to` | query | No | Window end, YYYY-MM-DD, inclusive and at most 366 days after from. Defaults to from + 30 days. |
| `types` | query | No | Comma-separated subset of lockup_expiry, quiet_period_expiry, listing. Defaults to all. |

```bash
curl -H "Authorization: Bearer ips_live_YOUR_KEY" \
  "https://iposignal.xyz/api/agent/ipo-events?types=lockup_expiry"
```

The payload is in `data`:

```json
{
  "version": "1",
  "data": {
    "from": "2026-09-01",
    "to": "2026-09-30",
    "types": [
      "lockup_expiry",
      "listing"
    ],
    "count": 2,
    "events": [
      {
        "date": "2026-09-18",
        "type": "listing",
        "company": "Electra Therapeutics, Inc.",
        "symbol": "ETRA",
        "cik": "0002088082",
        "exchange": "NASDAQ",
        "listing": {
          "offerPrice": 15,
          "firstDayOpen": 15,
          "firstDayClose": 13.25,
          "firstDayPopPct": 0,
          "firstDayCloseReturnPct": -11.67,
          "leadManagers": "Jefferies/TD Cowen/Evercore ISI/Cantor"
        }
      },
      {
        "date": "2026-09-27",
        "type": "lockup_expiry",
        "company": "HMH Holding Inc",
        "symbol": "HMH",
        "cik": "0002021880",
        "exchange": "NASDAQ",
        "lockupDays": 180
      }
    ]
  }
}
```

### Response fields

Every field can be null or absent when the source does not state it. Fields not listed here can appear; ignore the ones you do not know.

| Field | Type | Description |
| --- | --- | --- |
| `data.from` | string | Window start, YYYY-MM-DD. |
| `data.to` | string | Window end, YYYY-MM-DD, inclusive. |
| `data.types` | array of strings | Event types included. |
| `data.count` | integer | Events returned. |
| `data.events` | array of objects | Events in date order. |
| `data.events[].date` | string | Day of the event, YYYY-MM-DD. |
| `data.events[].type` | string | lockup_expiry (insiders may start selling), quiet_period_expiry (underwriters' analysts may start publishing) or listing (first trading day). |
| `data.events[].company` | string | Registrant name as filed with the SEC, e.g. Circle Internet Group, Inc. |
| `data.events[].symbol` | string | Ticker symbol the company trades under now, upper case, e.g. CRCL. |
| `data.events[].cik` | string | SEC Central Index Key: the registrant's permanent SEC identifier, as a 10-digit string with leading zeros, e.g. 0001876042. |
| `data.events[].exchange` | string | Listing exchange: NASDAQ, NYSE, NYSEAMER (NYSE American) or OTC. Other venues verbatim. |
| `data.events[].lockupDays` | integer | lockup_expiry only: length of the lock-up in days, typically 180. |
| `data.events[].listing` | object | listing events only: how the first day went. |
| `data.events[].listing.offerPrice` | number | Offer price, USD per share. Null for a direct listing. |
| `data.events[].listing.firstDayOpen` | number | First-day opening price, USD, as printed (not split-adjusted). |
| `data.events[].listing.firstDayClose` | number | First-day closing price, USD, as printed (not split-adjusted). |
| `data.events[].listing.firstDayPopPct` | number | (firstDayOpen − offerPrice) ÷ offerPrice, percent. |
| `data.events[].listing.firstDayCloseReturnPct` | number | (firstDayClose − offerPrice) ÷ offerPrice, percent. |
| `data.events[].listing.leadManagers` | string | Lead underwriters, as IPOScoop lists them. |

Errors besides the common ones: `400`. None is charged.


---

<!-- https://iposignal.xyz/docs/errors.md -->

# Quotas and errors

## Quotas

| Plan | Calls a month | Past the quota |
| --- | --- | --- |
| No key | None | Each paid call answers `402` with x402 terms |
| Free account key | 250 | Paid calls answer `402` with x402 terms |
| Subscription key | 10,000 | Paid calls answer `402` with x402 terms |

- Quotas are per account and reset on the 1st of each month, UTC.
- Only a delivered `200` counts. `X-API-Quota-Remaining` on the response says what is left.
- Free endpoints and free MCP tools do not count and need no key.
- There is no per-minute limit on top of the monthly quota.

## Status codes

| Status | Meaning | Charged | Retry |
| --- | --- | --- | --- |
| `200` | The payload. | Yes, on a paid endpoint |  |
| `400` | A parameter is missing or malformed. The `error` field says which. | No | After fixing the request |
| `401` | The API key is unknown or was revoked. | No | With a valid key |
| `402` | Payment required: no key was sent, or the key's quota is spent. The body carries the x402 terms and `error` gives the reason. | No | With a key, or with an x402 payment |
| `404` | Nothing matched: a ticker we do not cover, or data not computed yet. | No | No |
| `500` | Server error. | No | Yes |
| `503` | The database could not be reached. | No | Yes, after a pause |

Error bodies are JSON with an `error` string:

```json
{
  "error": "Provide exactly one of ?symbol= or ?name="
}
```

## On the MCP server

A tool reports a failure as a result marked `isError` with a sentence of text, not as a protocol error. A premium tool that found nothing says "You were not charged" in that text.

## Caching

A response paid for with an API key is sent with `Cache-Control: private, no-store`. Cache it yourself if you call the same thing repeatedly: most data changes at most daily.

Questions: [iposignal.xyz/faq](https://iposignal.xyz/faq).

---

<!-- https://iposignal.xyz/docs/changelog.md -->

# Changelog

## 2026-11-12

- API keys are free to create: any account gets 250 calls a month. Keys used to need a subscription.
- An OpenAPI 3.1 document at `/openapi.json`.
- These docs, each page also available as Markdown, plus `/skill.md` and `/llms-full.txt`.
- Sign-in for MCP clients: `/api/oauth/mcp` connects Claude, ChatGPT, Cursor and VS Code to your account over OAuth, with no key to paste.

## 2026-10-14

- MCP server 1.4.0: free `get_ipo_pipeline` and `get_ipo_filings` tools, three prompts and the `iposignal://guide` resource.

## 2026-09-23

- API keys for subscribers, as an alternative to paying per call over x402.
- IPO events endpoint and tool: lock-up expiries, quiet-period expiries and listings with first-day results.
- MCP tools split into free and premium tiers, with premium tools paid over x402 at the HTTP price.