Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wokelo.ai/llms.txt

Use this file to discover all available pages before exploring further.

1. Overview

The M&A Activity API gives you programmatic access to Wokelo’s curated database of merger and acquisition transactions for a given report. Each record surfaces the full deal context: who acquired whom, at what price, on what date, what the target company does, and the relevant news coverage — all structured and ready to query. This is a synchronous API — submitting a request returns the complete result set immediately. No polling is required. Each transaction in the result set includes:
  • Deal metadata — announced date, completion date, deal status, and disclosed transaction value
  • Acquirer profile — name, website, and buyer type (Strategic or Institutional)
  • Target firmographics — headquarters, founding year, employee count, and operating geography
  • Target business profile — product category, core offering description, and product catalog
  • News context — curated coverage excerpts with source URLs for deals with public reporting
Common use cases:
  • Deal sourcing and competitive intelligence — Track which strategic and institutional acquirers are most active in a sector. Identify consolidation patterns, serial acquirers, and emerging buyer profiles
  • Market mapping — Understand how a sector is consolidating by pulling all transactions within a product category, geography, or date range
  • Portfolio monitoring — Catch new deals involving companies in categories you track. Distinguish completed transactions from pending announcements using the Deal Status field
  • Due diligence enrichment — Pull prior acquisitions by a specific acquirer or in a comparable category to assemble precedent transaction context rapidly
  • Buyer screening — Identify which strategic and institutional buyers are most active in a space, segmented by acquirer type, deal size, and geography
This API is synchronous. A single POST request returns the complete transaction data immediately — no job polling required. See How Sync APIs work.

2. Quick Start

Step 1 — Submit the request
curl --location 'https://api.wokelo.ai/api/enterprise/ma-activity/' \
  --header 'Authorization: Bearer <YOUR_API_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "report_id": 1009657
  }'
Step 2 — Access the transactions
# The Grid object contains one key — extract the transactions array
transactions = list(data["Grid"].values())[0]
print(f"Retrieved {len(transactions)} transactions")
Step 3 — Work with the data
# Example: print each deal
for t in transactions:
    amount = t.get("Deal Amount ($M)")
    amount_str = f"${amount / 1e9:.1f}B" if amount else "undisclosed"
    print(f"{t['Acquirer Name']}{t['Target Name']} | {amount_str} | {t['Deal Status']}")

3. Authentication

All requests must include a Bearer token in the Authorization HTTP header. No other authentication method is supported.
Authorization: Bearer <YOUR_API_TOKEN>
API tokens are issued from your Wokelo account. Navigate to Account Details → API Credentials in the Wokelo dashboard to get your client id and client secret. Contact support@wokelo.ai if you do not yet have API access.
Never expose your token in client-side code, browser requests, or public repositories. A missing or invalid token returns 401 Unauthorized. A valid token without sufficient plan permissions returns 403 Forbidden.

4. Request Reference

Endpoint
POST https://api.wokelo.ai/api/enterprise/ma-activity/
The request body is JSON. The report_id is the only required parameter.
ParameterTypeRequiredDescription
report_idintegerRequiredThe unique identifier for the M&A report you want to retrieve. Find this in the URL when viewing a report in the Wokelo dashboard (app.wokelo.ai/reports/<report_id>) or via the Reports API.
Full request example:
curl --location 'https://api.wokelo.ai/api/enterprise/ma-activity/' \
  --header 'Authorization: Bearer <YOUR_API_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "report_id": 1009657
  }'

5. Response

Response structure

{
  "Grid": {
    "<workflow_key>": [ ...transaction objects... ]
  },
  "meta": {
    "report_id": 1009657,
    "title": "EV Charging Infra",
    "user": "you@yourcompany.com",
    "dt_createdon": "2026-05-13 11:26:20"
  }
}
FieldTypeDescription
GridobjectContains one key (a workflow identifier string) whose value is an array of transaction objects. Use list(data["Grid"].values())[0] to extract the array.
meta.report_idintegerThe report ID that was requested.
meta.titlestringHuman-readable title of the report.
meta.userstringEmail of the Wokelo user who created the report.
meta.dt_createdonstringISO 8601 datetime when the report was generated.

Transaction object fields

Each object in the transactions array contains the following fields: Deal identity
FieldTypeDescription
PermalinkstringStable unique identifier for this transaction (e.g. "siemens-acquires-heliox--d575a4c7"). Use this as a primary key when storing transactions.
Deal Date (Announced)stringISO 8601 date when the deal was announced (YYYY-MM-DD).
Deal Completion Datestring | nullISO 8601 date when the deal closed. Null for pending deals or where the close date was not reported.
Deal Statusstring"Complete" or "Pending".
Deal Amount ($M)float | nullTotal transaction value. Null when undisclosed. See the note on units below.
Acquirer
FieldTypeDescription
Acquirer NamestringDisplay name of the acquiring company.
Acquirer WebsitestringPrimary domain of the acquirer (e.g. "siemens.com").
Acquirer Typestring"Strategic" for operating companies; "Institutional" for financial buyers (private equity, infrastructure funds, family offices).
Target identity & firmographics
FieldTypeDescription
Target NamestringDisplay name of the acquired company.
Target Websitestring | nullPrimary domain of the target. Null when not available.
Target HQ Citystring | nullHeadquarters city of the target.
Target HQ Countrystring | nullHeadquarters country of the target.
Target HQ Continentstring | nullHeadquarters continent of the target.
Target Foundedstring | nullYear the target company was founded.
Target Employees (Crunchbase)string | nullEmployee headcount band from Crunchbase (e.g. "51-100").
Target Employees (LinkedIn)integer | nullNumeric employee count from LinkedIn.
Target business profile
FieldTypeDescription
Target Product Categorystring | nullShort label for the target’s primary product or service category (e.g. "Electric Vehicle Charging Infrastructure").
Target Core Offeringstring | nullAI-generated 2–4 sentence description of what the target does, its customers, and its market position.
Target Product Catalogstring | nullComma-separated list of key products and services.
News
FieldTypeDescription
Newsstring | nullConcatenated news coverage for the transaction. Each section contains a prose summary followed by a source URL on a new line. Multiple coverage items are separated by blank lines. Null when no coverage was indexed.
The News field is unstructured text, not JSON. Parse it by splitting on newlines and identifying lines that start with http to extract source URLs separately from prose summaries.

Deal Amount units

The Deal Amount ($M) field is labelled in millions but stored values are in raw USD. A deal reported as “$1.1 billion” is stored as 1100000000.0. Always convert before displaying:
amount_raw = transaction["Deal Amount ($M)"]
if amount_raw:
    amount_bn = amount_raw / 1e9   # billions
    amount_m  = amount_raw / 1e6   # millions

Notes on null values

Several fields are frequently null, and this is expected:
  • Deal Amount ($M) — The majority of M&A transactions are not publicly disclosed. Null means undisclosed, not zero.
  • Target Core Offering and Target Product Category — Null for targets where Wokelo’s enrichment pipeline did not find sufficient public information.
  • Deal Completion Date — Null for pending deals and for completed deals where the close date was not reported.
  • News — Null when no news coverage was indexed for the transaction.

6. Examples

Retrieving and filtering a full report

Retrieve all transactions in a report and filter to completed deals over $1 billion.
curl --location 'https://api.wokelo.ai/api/enterprise/ma-activity/' \
  --header 'Authorization: Bearer <YOUR_API_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "report_id": 1009657
  }'
Sample response (excerpt):
{
  "Grid": {
    "Acquisition Workflow - Grid_419a21d1-32e0-4c10-a6bd-6f6cc100187c": [
      {
        "Permalink": "siemens-acquires-heliox--d575a4c7",
        "Target Name": "Heliox",
        "Target Website": "heliox-energy.com",
        "Acquirer Name": "Siemens",
        "Acquirer Website": "siemens.com",
        "Acquirer Type": "Strategic",
        "Deal Amount ($M)": null,
        "Deal Date (Announced)": "2023-08-22",
        "Deal Completion Date": "2024-01-11",
        "Deal Status": "Complete",
        "Target HQ City": "Best",
        "Target HQ Country": "Netherlands",
        "Target HQ Continent": "Europe",
        "Target Founded": "2009",
        "Target Product Category": "Electric Vehicle Charging Infrastructure",
        "Target Core Offering": "Heliox specializes in innovative electric vehicle charging solutions, particularly for heavy-duty applications such as buses and trucks, providing fast charging technology and related services for reliable operation.",
        "Target Product Catalog": "Switch mode power technology products, Customized products and services",
        "Target Employees (Crunchbase)": "11-50",
        "Target Employees (LinkedIn)": 252,
        "News": null
      },
      {
        "Permalink": "gdf-suez-acquires-uk-power-networks--d7f01b2c",
        "Target Name": "UK Power Networks",
        "Target Website": "ukpowernetworks.co.uk",
        "Acquirer Name": "Engie",
        "Acquirer Website": "engie.com",
        "Acquirer Type": "Strategic",
        "Deal Amount ($M)": 14194943896.0,
        "Deal Date (Announced)": "2026-02-25",
        "Deal Completion Date": null,
        "Deal Status": "Complete",
        "Target HQ City": "London",
        "Target HQ Country": "United Kingdom",
        "Target HQ Continent": "Europe",
        "Target Founded": "2010",
        "Target Product Category": null,
        "Target Core Offering": null,
        "Target Product Catalog": null,
        "Target Employees (Crunchbase)": "5001-10000",
        "Target Employees (LinkedIn)": 3223,
        "News": "ENGIE is set to acquire UK Power Networks from CKI, pending regulatory approval...\nhttps://www.ukpowernetworks.co.uk/news/engie-announces-the-acquisition-of-uk-power-networks\n\nA French utility company, Engie, plans to acquire UK Power Networks for over $14 billion.\nhttps://www.tradingview.com/news/reuters.com,2026:newsml_L4N3ZL1YH:0-french-utility-engie-to-acquire-uk-power-networks-for-over-14-billion/"
      }
    ]
  },
  "meta": {
    "report_id": 1009657,
    "title": "EV Charging Infra",
    "user": "you@yourcompany.com",
    "dt_createdon": "2026-05-13 11:26:20"
  }
}

Grouping transactions by acquirer

Build an acquirer activity profile to identify the most active buyers in a sector — useful for buyer targeting and market structure analysis.
from collections import defaultdict

transactions = list(data["Grid"].values())[0]
by_acquirer = defaultdict(list)

for t in transactions:
    by_acquirer[t["Acquirer Name"]].append(t)

# Sort by deal count, most active first
for acquirer, deals in sorted(by_acquirer.items(), key=lambda x: -len(x[1])):
    completed = sum(1 for d in deals if d["Deal Status"] == "Complete")
    pending   = sum(1 for d in deals if d["Deal Status"] == "Pending")
    print(f"{acquirer}: {len(deals)} deals ({completed} complete, {pending} pending)")
    for d in deals:
        print(f"  → {d['Target Name']} ({d['Deal Date (Announced)'][:4]})")
Sample output:
Siemens: 15 deals (14 complete, 1 pending)
  → Heliox (2023)
  → Trayer Engineering (2024)
  → Altair (2024)
  → Dotmatics (2025)
  ...
TotalEnergies: 10 deals (8 complete, 2 pending)
  → Total Eren (2023)
  → Kyon Energy (2024)
  → VSB Group (2024)
  ...

Filtering by product category with news

Filter transactions to a specific product category and surface deals with news coverage for deeper context.
category_keyword = "Electric Vehicle Charging"

ev_charging = [
    t for t in transactions
    if t.get("Target Product Category")
    and category_keyword.lower() in t["Target Product Category"].lower()
]

with_news = [t for t in ev_charging if t.get("News")]

print(f"Found {len(ev_charging)} EV charging deals, {len(with_news)} with news coverage\n")

for t in with_news:
    urls = [line.strip() for line in t["News"].split("\n")
            if line.strip().startswith("http")]
    print(f"{t['Acquirer Name']}{t['Target Name']} | {t['Deal Date (Announced)']}")
    if urls:
        print(f"  Source: {urls[0]}")
    print()

7. Error Handling

The API uses standard HTTP status codes. All error responses include a JSON body with a detail or message field.
StatusMeaningCause & Resolution
200 OKSuccessResults returned successfully.
400 Bad RequestInvalid parametersA required field is missing or a parameter value is invalid — e.g. missing report_id or a non-integer value. Check the detail field.
401 UnauthorizedAuth failedThe Authorization header is missing, malformed, or contains an invalid token. Verify your key in Settings → API Keys.
403 ForbiddenInsufficient accessYour plan does not include access to this endpoint or report. Contact support@wokelo.ai to review your plan.
404 Not FoundResource not foundThe report_id does not exist or is not accessible to your account. Confirm the ID in your dashboard.
429 Too Many RequestsRate limit exceededImplement exponential back-off. The response includes a Retry-After header.
500 Internal Server ErrorServer errorRetry after a brief delay. If the issue persists, contact support@wokelo.ai with your report_id.
Error response example:
{
  "status": "error",
  "detail": "Report with id '9999999' could not be found."
}
Retry logic with exponential back-off:
import time, requests

def fetch_with_retry(report_id, api_key, max_retries=3):
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    for attempt in range(max_retries):
        try:
            response = requests.post(
                "https://api.wokelo.ai/api/enterprise/ma-activity/",
                headers=headers,
                json={"report_id": report_id},
                timeout=30
            )
            if response.status_code == 429:
                wait = 2 ** attempt   # 1s, 2s, 4s
                time.sleep(wait)
                continue
            response.raise_for_status()
            return response.json()
        except requests.exceptions.Timeout:
            if attempt == max_retries - 1:
                raise
            time.sleep(1)
    raise Exception(f"Failed after {max_retries} attempts")

8. Best Practices

Use the Permalink field as a stable identifier If you’re storing transactions in your own database or CRM, use Permalink as the primary key. It is a stable, unique identifier for each transaction that persists across API versions and report refreshes:
transaction_map = {t["Permalink"]: t for t in transactions}
Handle null values defensively Many fields are null for legitimate reasons — especially Deal Amount ($M). Always guard before operating on field values:
# ❌ Throws on deals with undisclosed amounts
total = sum(t["Deal Amount ($M)"] for t in transactions)

# ✅ Safe — treat null as zero for aggregation
total = sum(t.get("Deal Amount ($M)") or 0 for t in transactions)
disclosed = [t for t in transactions if t.get("Deal Amount ($M)") is not None]
Parse the News field as structured text The News field is a multi-section string, not JSON. Each section contains a prose summary followed by a source URL. Parse it by splitting on newlines:
def extract_news_urls(news_text):
    if not news_text:
        return []
    return [line.strip() for line in news_text.split("\n")
            if line.strip().startswith("http")]

def extract_news_summaries(news_text):
    if not news_text:
        return []
    return [line.strip() for line in news_text.split("\n")
            if line.strip() and not line.strip().startswith("http")]
Account for the Deal Amount ($M) unit quirk Despite the field name suggesting millions, the stored values are raw USD. Always convert before displaying or aggregating:
raw = t.get("Deal Amount ($M)")
if raw and raw >= 1e9:
    display = f"${raw / 1e9:.1f}B"
elif raw:
    display = f"${raw / 1e6:.0f}M"
else:
    display = "Undisclosed"
Cache responses for analytics workloads M&A reports are relatively static — a report generated today won’t change minute-to-minute. For dashboards or batch pipelines, cache the full response locally and refresh on a schedule (e.g. daily) rather than calling the API on every page load or query. Use both Acquirer Type and Acquirer Name to profile the buyer landscape Acquirer Type ("Strategic" vs "Institutional") gives you the high-level split. Grouping by Acquirer Name lets you identify serial acquirers — companies appearing five or more times in a sector are a meaningful signal for buyer targeting or market structure analysis. Use Deal Status to monitor live transactions Filter to "Pending" deals to track active announcements that haven’t yet closed. Re-querying the same report over time surfaces status transitions as pending deals complete, giving you a lightweight deal-tracking workflow without building a separate monitoring layer. Iterate your report scope, not just your client-side filters If the returned transaction set doesn’t cover the geography, time range, or sub-sector you need, contact your Wokelo account manager to create or refine the underlying report. The richness of the API output is directly dependent on how the report scope was configured.

Target Screening

Identify and score potential acquisition targets for a defined acquirer — AI-ranked with deal feasibility, synergy, and precedent scores.

Buyer Screening

Identify and score potential acquirers for a target company — the inverse of Target Screening.

Market Map

Discover and map all companies competing in a specific market or product category.

Company Deep Intelligence

Generate deep AI intelligence on any acquirer or target — business model, financials, strategy, and M&A history.

Company Instant Enrichment

Synchronously enrich firmographic and financial data for any company in the transaction set.

Industry Deep Intelligence

Generate a deep intelligence report on the sector behind the deal activity for thesis development.