Subscribe to what happens.
Evinor turns what happens in the world into structured events — typed, deduplicated, tied to canonical entities. Extracted from what’s reported today, published structured at the source tomorrow. Pushed to your workflows, or pulled by your agents.
Portfolio raises ≥ $20M
- WHEN
- Investment (funding round)FUND_RAISING
- INVOLVING
- watchlist “Portfolio”
- ONLY IF
- amount raised ≥ $20Mreported by ≥ 3 independent sources
- THEN
- POST https://your-app.example/hooks/evinorSlack #deals
POST https://your-app.example/hooks/evinor attempt 1 · 200 OK Content-Type: application/json X-Evinor-Signature: 8/FaI+Q/E4js5FwvALpBv9KSCyJ51ANwdlX2FTwRQgU=
{ "protocolVersion": "0.1", "plane": "data", "type": "incident", "messageId": "42a98f3d-3ee0-4518-a8e2-3699af60fa6d", "subjectId": "54ae056c-9114-4f64-a3a4-c7a2ce36c663", "idempotencyKey": "e955c2e0-4d57-4767-a333-f2e211d2ff1e", "timestamp": "2026-09-30T14:21:07.000Z", "sender": { "agentId": "evinor-incident-rules", "keyId": "9c4f5d2a-1b3e-4f8a-a5d6-7e2c8b9f1a3d:1", "signatureAlg": "hmac-sha256", "signature": "8/FaI+Q/E4js5FwvALpBv9KSCyJ51ANwdlX2FTwRQgU=" }, "recipients": { "kind": "incident-rule-action", "actionType": "GENERIC_WEBHOOK", "actionId": "44addaa0-8862-4cba-ac50-ba9ae18f2ec7" }, "provenance": [ { "sourceKind": "external", "sourceId": "17bd0509-6d54-4d15-a0c3-3aa2c4d365da", "sourceName": "Outlet A" }, { "sourceKind": "external", "sourceId": "f5499004-248d-4fff-a476-7f9fd0e9f3a0", "sourceName": "Outlet B" }, { "sourceKind": "user", "sourceId": "8b2b94ee-25dd-423f-a920-f8fb468a1c78", "sourceName": "Helio Labs Comms" } ], "payload": { "eventType": "2de62c11-2546-4df3-ae94-69efe87a8531", "eventCodeName": "FUND_RAISING", "occurredAt": "2026-09-30T14:16:07.000Z", "externalEventId": "5d251524-fe9c-4ec1-ad02-64a86ee202ae", "details": { "incidentId": "5d251524-fe9c-4ec1-ad02-64a86ee202ae", "incidentReportId": "cd39221c-896d-4cb0-aaad-271b9cfc401b", "templateId": "2de62c11-2546-4df3-ae94-69efe87a8531", "templateCodeName": "FUND_RAISING", "templateDisplayName": "Investment", "generatedSentence": "Helio Labs raised $40M in a Series B led by Northwind Ventures.", "matchingReportCount": 3, "reportingOutlets": [ { "id": "17bd0509-6d54-4d15-a0c3-3aa2c4d365da", "name": "Outlet A" }, { "id": "f5499004-248d-4fff-a476-7f9fd0e9f3a0", "name": "Outlet B" } ], "roles": [ { "code": "COMPANY_RAISING_FUNDS", "textValue": "Helio Labs", "namedEntityId": "ee3e6b81-80c1-4e88-aba1-af50fd1f5cba" }, { "code": "INVESTING_COMPANY_NAME", "textValue": "Northwind Ventures", "namedEntityId": "ae7ee645-455f-46ef-a6f2-fe9c10636312" }, { "code": "AMOUNT_RAISED", "textValue": "$40M", "parsedAmount": 40000000 }, { "code": "FUNDING_ROUND_TYPE", "textValue": "Series B" } ], "confidence": { "score": 0.91, "band": "HIGH", "formulaVersion": 2 }, "coverImageUrl": null, "matchedAt": "2026-09-30T14:21:06.000Z" } }}↑ Example data. This is the envelope your endpoint receives.Select a delivery to inspect it.
The information exists. The event doesn’t.
Inside software, everything is an event: typed, deduplicated, delivered once. A payment, a deploy, a signup.
Outside it, what happens in the world arrives as prose — the same acquisition told forty ways, by forty outlets, for people to read.
So every team, and now every agent, re-reads the web to find out what changed.
Evinor is the event layer for the real world.
Read the manifesto →Every team rebuilds the same scrapers, polling jobs, and LLM loops to catch the same changes — paying separately and getting results they can’t trust or reuse.
team_a ── scraper ────── llm ──┐ team_b ── news poll ──── llm ──┤ team_c ── scraper ────── llm ──┼──▶ same funding round, detected 4× team_d ── rss poll ───── llm ──┘ 4 bills · 4 different answers
outlet ──┐
outlet ──┼──▶ evinor ──▶ one event ──┬──▶ team_a webhook
outlet ──┤ ├──▶ team_b slack
report ──┘ ├──▶ team_c rest search
└──▶ team_d agent via mcpAgents shouldn’t have to read the news.
Helio Labs, the Toronto-based battery-analytics startup, said Tuesday it has closed a $40 million Series B. The round was led by Northwind Ventures, with participation from existing backers, according to a person familiar with the matter. The company, which also goes by Helio, plans to double its engineering team…
- COMPANY_RAISING_FUNDS
- Helio Labs
- INVESTING_COMPANY_NAME
- Northwind Ventures
- AMOUNT_RAISED
- $40M 40000000
- FUNDING_ROUND_TYPE
- Series B
- reportingOutlets
- 3
- confidence.band
- HIGH
Deterministic
Branch on a field, not on how a model read a paragraph today.
Cheap to consume
An agent reads a small typed object instead of re-reading articles.
Verifiable
Every event carries its sources and counts; check before you act.
Composable
Filter, join, and act on fields: amount ≥ $20M, entity in your list.
Reported many times. Delivered once.
Collect
News coverage from many outlets, plus first-hand reports published directly by companies and people close to the event.
- Outlet A
- Outlet B
- Outlet C
- Helio Labs Comms
- first-hand
Structure
Each happening becomes one typed event with extracted roles, each role linked to a canonical entity.
- COMPANY_RAISING_FUNDS
- Helio Labs
- INVESTING_COMPANY_NAME
- Northwind Ventures
- AMOUNT_RAISED
- $40M
- FUNDING_ROUND_TYPE
- Series B
Match
Your sensors decide what’s worth waking you up for. You set the bar.
- watchlist Portfolio
- ✓
- amount $40M ≥ $20M
- ✓
- sources 3 ≥ 3
- ✓
- sensor
- match
Deliver
Push to a webhook or Slack. Pull through the REST API, TypeScript SDK, or MCP.
- push · webhook
- 200
- push · slack
- pull · rest
- pull · mcp
One happening. One event. Delivered once.
Forty articles. One event. One delivery.
Matching and entity resolution happen before anything reaches you. That’s why you can trust the event you receive.
Matched across outlets
Coverage of the same happening from many outlets becomes one event, so your workflow runs once — not once per article.
One canonical entity
Watch “Databricks” and you also catch “DBX” and “Databricks, Inc.” If two entity records turn out to be the same company, results follow the surviving one.
Delivered once, safe to retry
Each sensor delivers an event once, with an idempotencyKey that stays the same across retries, so you can dedupe safely.
Evidence travels with it
The event keeps counting sources after delivery: how many outlets reported it, and which ones.
Structured twice: when it’s read, and when it’s published.
Today most of what happens is published as prose, so Evinor structures it as it’s read. But the best time to structure a fact is when it’s first published — by the company it’s about, or the person who saw it first-hand. Evinor does both, into the same events.
Extracted from coverage across many outlets, matched into one event.
POST /v1/reports{ "event_type_id": "<Investment event type id>", "happened_at": "2026-09-14T12:30:00Z", "roles": [ { "role": "COMPANY_RAISING_FUNDS", "entity_id": "5c1d2e3f-…" }, { "role": "INVESTING_COMPANY_NAME", "entity_id": "8a0b7c6d-…" }, { "role": "AMOUNT_RAISED", "amount": { "value": 40000000, "unit": "USD" } }, { "role": "FUNDING_ROUND_TYPE", "text": "Series B" } ], "description": "Helio Labs closed a $40M Series B led by Northwind Ventures.", "grant_id": "<Helio Labs reporting grant id>"}Filed structured at the source — no parsing, no guessing, attributed to who published it.
Publish from the web app, the REST API, or an agent over MCP.
Published under your name, or on behalf of your company.
Subscribers can choose events backed by first-hand reports.
The more of the world that’s published structured, the less of it anyone has to parse.
Publisher revenue share is in the works — talk to us.
Decide what’s worth waking you up for.
Low-stakes workflows can fire on the first credible report. High-stakes ones can wait for more independent sources. You choose, per sensor.
Backtest any sensor against the last 7 or 30 days before you enable it. Building sensors and backtesting are free.
What Evinor detects
Event types are schemas on one engine, not separate products — the catalog grows without rebuilding anything.
Acquisition
ACQUISITIONOne company acquires another.
Investment
FUND_RAISINGA company raises a funding round.
Layoff
LAYOFFA company cuts jobs.
Leadership Change
LEADERSHIP_CHANGESomeone takes up or leaves a leadership role.
IPO
IPOA company lists on a stock exchange.
Partnership Announcement
PARTNERSHIP_ANNOUNCEMENTTwo companies announce a partnership.
Product Launch
PRODUCT_LAUNCHA company launches a new product, version, feature, capability, content, or access change.
Package vulnerability
Security breach
New job opening
Insolvency / bankruptcy
Product recall
Lawsuit filed
Regulatory action
Be told, or ask.
Your agent can search what already happened and be told what happens next. Evinor delivers the event; acting on it happens in your workflow or agent.
A sensor fires. You get a signed POST.
Delivered to your webhook, or as a Slack message. n8n, Zapier, and Make work today through the signed webhook; native integrations are coming soon.
Search what already happened.
Same filter vocabulary as sensors, up to a year back, from the REST API, the TypeScript SDK, or MCP so an agent can query it directly.
curl https://api.evinor.ai/v1/sensors \ -H "Authorization: Bearer $EVINOR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Series B+ in our portfolio", "filter": { "event_type_id": "<Investment event type id>", "involved_entity_list_ids": ["<Portfolio watchlist id>"], "min_reports": 3 }, "actions": [ { "type": "generic_webhook", "generic_webhook": { "url": "https://your-app.example/hooks/evinor" } } ] }'import { Evinor } from '@evinor/sdk'; const evinor = new Evinor(); // reads EVINOR_API_KEY // What already happened — one billed search, free pagination.for await (const event of evinor.events.searchAll({ event_type_id: investmentTypeId, involved_entity_list_ids: [portfolioListId], lookback_days: 90,})) { console.log(event.first_report_date, event.sentence);}import { verifyWebhook } from '@evinor/sdk'; app.post('/hooks/evinor', express.text({ type: '*/*' }), async (req, res) => { const ok = await verifyWebhook({ payload: req.body, // raw body signature: req.get('X-Evinor-Signature') ?? '', secret: process.env.EVINOR_SIGNING_SECRET ?? '', }); if (!ok) return res.status(401).end(); // dedupe on envelope.idempotencyKey, then act res.status(204).end();});// hosted{ "mcpServers": { "evinor": { "url": "https://api.evinor.ai/mcp", "headers": { "Authorization": "Bearer evnr_live_…" } } }} // local, via npx{ "mcpServers": { "evinor": { "command": "npx", "args": ["-y", "@evinor/mcp"], "env": { "EVINOR_API_KEY": "evnr_live_…" } } }} // tools: search_events · search_events_continue · list_event_types// list_reporting_grants · submit_reportAgents are starting to act, not just answer.
Software that acts unattended needs inputs it can trust and branch on — not paragraphs it has to interpret.
Extraction finally works.
Language models made it practical to turn prose into typed events at scale — the read-time half of this couldn’t exist a few years ago.
Agents can plug in.
With MCP, any agent can search what happened and file what it knows, through one connection.
idempotencyKey across retriesBuild it yourself, or call a research API?
| Capability | Evinor | DIY scrapers + LLM loops | Per-request research APIs |
|---|---|---|---|
| One event per happening | Yes: Matched across outlets before it reaches you | No: Every team re-detects and re-dedupes | No: Re-researched on every request |
| Canonical entities | Yes: Aliases resolve to one entity you can key on | Partly: Fuzzy matching downstream | Partly: Varies |
| You set the bar | Yes: Per-sensor source thresholds and role conditions | Partly: Build it yourself | No: Rarely |
| Push and pull | Yes: Webhook, Slack, REST, SDK, MCP | Partly: Your cron jobs | Partly: Mostly polling |
| History | Yes: Search up to 365 days back | Partly: Only what you stored | Partly: Depends on the provider |
| Cost as you grow | Yes: Detection is shared across subscribers | No: Grows with every team and source | No: Grows with every request |
Subscribe to what happens.
The event layer for the real world.
Free tier — no card required.