Overview

The Evergreen API is a REST API that runs investment-grade company research via a 7-stage multi-agent pipeline. Submit a research task with a company name, a question, and an optional structured extraction schema — receive verified findings, claims, an optional full report, and structured data in minutes.

Base URL

https://api.acqwired.com/v1

Protocol

HTTPS only

Format

JSON

Quick start

1. Obtain your API key from the dashboard. 2. Submit a research task via POST /research. 3. Poll GET /task/{taskId} until status === "completed". 4. Read structured_output.result for your structured output.

Authentication

All endpoints except GET /health require an API key sent as a Bearer token in the Authorization header.

Request header
Authorization: Bearer YOUR_API_KEY
curl example
curl -X POST https://api.acqwired.com/v1/research \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "company_name": "Acme Manufacturing", "question": "Is this a good PE target?" }'

API Keys

API keys are generated in the dashboard under your user profile. Each key is scoped to your organization. Keys are not rotated automatically — contact your admin to revoke or regenerate.

Endpoints

All endpoints are relative to the base URL.

POST/research

Queue a new research task. Processing is asynchronous — returns immediately with a taskId (202). Poll GET /task/{taskId} for results. Schema is optional: omit both schema and schema_id to let the API auto-resolve one from your question.

Schema resolution order

  1. schema_id — use a specific saved schema by ID
  2. schema — define a schema inline in the request
  3. Auto-resolve — omit both: the API calls AI to derive a keyName from the question, then reuses a matching saved schema or creates one automatically

Request Body

company_namestringrequired

Full legal or trade name of the company to research.

domainstring

Company website domain (e.g. "acmemfg.com"). Improves research accuracy. Required when completeCompanyProfile is true.

questionstring

The research question. Required unless completeCompanyProfile is true. Can be broad ("Is this a good PE target?") or specific ("What quality certifications do they hold?").

completeCompanyProfileboolean

When true, runs a full company intelligence analysis across 4 parallel pipelines (identity, operations, contacts, people). Returns a rich structured result with 40+ classified fields and confidence scores. question, schema, and schema_id are ignored when this flag is set. Defaults to false.

thesis_textstring

Investment thesis text (only used when completeCompanyProfile is true). When provided, the response includes a thesis section with thesis_fit_score (0–100), thesis_alignment (Excellent / Good / Moderate / Poor Fit), and thesis_fit_justification.

schemaobject

Inline schema definition for structured extraction. See Schema Types. Mutually exclusive with schema_id. Omit both to auto-resolve.

schema.keyNamestring

Output field name (e.g. "ceo_name"). Used as the key in structured_output.result.

schema.keyDescriptionstring

Description of what the field should capture.

schema.keyDataType"categorical" | "string" | "number"

Data type of the extracted field.

schema.keyOptionsstring[]

Required when keyDataType is "categorical". List of allowed options.

schema.enumType"best" | "all" | "topN"

Result mode for categorical schemas. "best" returns a single best match (default), "all" returns all matching options comma-separated, "topN" returns the top N matches.

schema.enumTopNnumber

Number of results when enumType is "topN". Defaults to 3.

schema_idstring

ID of a saved schema. Mutually exclusive with inline schema. Omit both to auto-resolve.

generateReportboolean

If true, the pipeline generates a full markdown report (stage 6). Defaults to false. Not applicable when completeCompanyProfile is true.

evergreen"auto" | "store_only" | "off"

How the task uses the Evergreen Index. Only applies when your organization has Index-first research enabled. "auto" (default): answer from the company's stored pages and earlier searches when they settle the question, otherwise run web research. "store_only": always run web research, but still save the pages and search results it fetches into the Index. "off": neither read nor write the Index. "store_only" and "off" always run a fresh task — they skip the 7-day result cache. The response echoes the value applied.

callback_urlstring

URL to POST to when the task reaches a terminal state (completed or failed). Retried up to 3 times with 1s/2s/4s backoff.

callback_tokenstring

Bearer token sent in the Authorization header of each callback request. Required if callback_url is set.

callback_contextstring

Arbitrary string echoed back in the callback payload as "context". Use to correlate callbacks with your own records (e.g. a CRM row ID).

Response — 202 Accepted

Response body
{
  "taskId": "task_9f2a4c1e",
  "status": "queued",
  "message": "Research task submitted successfully",
  "schemaId": "schema_abc123"  // present for standard research tasks
}
curl — minimal (schema auto-resolved)
curl -X POST https://api.acqwired.com/v1/research \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Manufacturing",
    "domain": "acmemfg.com",
    "question": "Who is the CEO?"
  }'
curl — complete company profile
curl -X POST https://api.acqwired.com/v1/research \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Manufacturing",
    "domain": "acmemfg.com",
    "completeCompanyProfile": true
  }'
curl — with callback
curl -X POST https://api.acqwired.com/v1/research \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Manufacturing",
    "domain": "acmemfg.com",
    "question": "Is this a good PE target?",
    "callback_url": "https://your-app.com/webhooks/research",
    "callback_token": "whsec_abc123",
    "callback_context": "crm_row_7821"
  }'

Callback payload

When the task reaches a terminal state the API POSTs this JSON to your callback_url with Authorization: Bearer {callback_token}. Retried up to 3 times (1 s / 2 s / 4 s backoff).

{
  "taskId":       "550e8400-e29b-41d4-a716-446655440000",
  "status":       "completed",           // or "failed"
  "context":      "crm_row_7821",        // echoed from callback_context
  "result":       { ... },               // structured_output (or full profile) — null on failure
  "errorMessage": null                   // error string when status is "failed"
}
curl — with explicit schema
curl -X POST https://api.acqwired.com/v1/research \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Manufacturing",
    "domain": "acmemfg.com",
    "question": "Is this an ideal PE acquisition target?",
    "schema": {
      "keyName": "AcquisitionScore",
      "keyDescription": "Overall acquisition attractiveness",
      "keyDataType": "categorical",
      "keyOptions": [
        "5 = Highly attractive",
        "4 = Attractive",
        "3 = Neutral",
        "2 = Unattractive",
        "1 = Pass"
      ]
    }
  }'
GET/research/{taskId}

Lightweight status check that reads directly from DynamoDB. Returns task metadata and current status, but not full results (structured output, claims, report). Use GET /task/{taskId} for complete results.

Response Fields

taskIdstringrequired

Unique task identifier.

status"pending" | "queued" | "active" | "in-progress" | "completed" | "failed"required

Current task status.

taskType"research" | "company_profile"required

"research" for standard lite/deep tasks; "company_profile" when completeCompanyProfile was true.

companyNamestringrequired

Company name as submitted.

domainstring

Company domain as submitted.

questionstring

Research question as submitted. Absent for company_profile tasks.

schemaobject

Schema definition used for this task. Absent for company_profile tasks.

schemaIdstring

Saved schema ID if one was used. Absent for company_profile tasks.

thesisstring | null

Investment thesis text submitted with the task. Present only for company_profile tasks where thesis_text was provided.

createdAtISO 8601 stringrequired

Task creation timestamp.

updatedAtISO 8601 string

Last update timestamp.

completedAtISO 8601 string

Completion timestamp. Present when status is "completed".

errorMessagestring

Error description when status is "failed".

curl example
curl https://api.acqwired.com/v1/research/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/task/{taskId}

Retrieve the current status and results of a research task. Poll this endpoint until status equals 'completed' or 'failed'. Standard research tasks typically resolve within 2–5 minutes. Company profile tasks typically resolve within 3–8 minutes.

Standard research tasks (taskType: "lite" or "deep")

Response Fields

taskIdstringrequired

Unique task identifier.

status"pending" | "queued" | "active" | "in-progress" | "completed" | "failed"required

Current pipeline status.

taskType"lite" | "deep" | "company_profile"

Type of task.

companyNamestringrequired

Company name as submitted.

domainstring

Company domain as submitted.

questionstring

Research question as submitted.

currentStagestring

Name of the currently executing pipeline stage.

webSearchesCountnumber

Total web searches performed across all stages.

executionTimeMsnumber

Total pipeline execution time in milliseconds.

tokenUsagenumber

Total LLM tokens consumed by the task.

reconstructCountnumber

Number of reconstruct operations performed on this task.

structured_output.resultobject

Extracted values matching your schema definition. Keys match the keyName you defined. Present when status is "completed".

structured_output.confidencenumber

Pipeline confidence score (0–100).

structured_output.justificationstring

AI reasoning for the extracted values.

structured_output.stepsstring[]

Steps taken to arrive at the result.

structured_output.sourcesarray

Cited sources: [{title, url, description}].

reportstring

Full markdown report. Present only if generateReport was true.

claimsstring

Markdown-formatted verified claims extracted from research.

errorMessagestring

Error description when status is "failed".

Response — standard task (completed)
{
  "taskId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "taskType": "lite",
  "companyName": "Acme Manufacturing",
  "domain": "acmemfg.com",
  "question": "Is this an ideal PE acquisition target?",
  "executionTimeMs": 187432,
  "tokenUsage": 41203,
  "webSearchesCount": 14,
  "structured_output": {
    "result": { "AcquisitionScore": "4 = Attractive" },
    "confidence": 84,
    "justification": "Acme Manufacturing demonstrates strong acquisition appeal...",
    "sources": [
      { "title": "Acme Manufacturing — Company Overview", "url": "https://acmemfg.com/about", "description": "Company overview page" }
    ]
  },
  "claims": "- Founded in 1994\n- ~340 employees\n- ISO 9001 certified"
}

Company profile tasks (taskType: "company_profile")

When completeCompanyProfile: true was set on submission, the completed response contains a structured multi-section result instead of structured_output. Each field includes a confidence score (0–100) and null fields are omitted.

taskIdstringrequired

Unique task identifier.

status"queued" | "running" | "completed" | "failed"required

Current task status.

taskType"company_profile"required

Always "company_profile" for this task type.

companyNamestringrequired

Company name as submitted.

domainstringrequired

Resolved company domain.

completedAtISO 8601 string

Timestamp when analysis completed.

tokenUsageobject

Token consumption breakdown: { inputTokens, outputTokens, totalTokens, model }.

identityobject

Core company identity fields. Keys: official_name, domain, company_summary, industry_niche, customer_segments, founding_year, headquarters, employee_count, total_customers, company_size, business_model.

operationsobject

Operational profile. Keys: operational_scale, operational_volume_metrics, geographic_footprint, remote_vs_office.

contactobject

Contact information. Keys: primary_email, primary_phone, physical_address, contact_form_url, linkedin_company_url.

peopleobject

Key people. Keys: ceo_name, ceo_email, ceo_linkedin_url, founder_name, founder_linkedin_url, other_executives, best_outreach_contact.

indicatorsobject

Categorical classification indicators. Keys: Cap Table Status, Employee Headcount Size, Geographic Reach, Primary Headquarters Region, Product Category, Delivery Model Type, Primary GTM Motion, Management Structure Type, Primary Competitive Position, Competitive Advantage, contact_availability, social_presence_strength, decision_maker_accessibility.

thesisobject

Thesis fit analysis. Present only when thesis_text was supplied on submission. Keys: thesis_fit_score (0–100 integer), thesis_alignment (Excellent / Good / Moderate / Poor Fit), thesis_fit_justification (string). Each field: { value, confidence }.

insightsarray

Dynamic facts discovered during research that fall outside standard schema fields. Each item: { field, value, source? }.

errorsarray

Per-pipeline errors if any pipeline partially failed: [{ name, error }].

errorMessagestring

Top-level error when status is "failed".

Response — company profile (completed)
{
  "taskId": "47463e01-7f03-4065-998c-e36b63b9e2bd",
  "status": "completed",
  "taskType": "company_profile",
  "companyName": "Acme Manufacturing",
  "domain": "acmemfg.com",
  "completedAt": "2026-05-26T14:22:11.000Z",
  "tokenUsage": {
    "inputTokens": 84210,
    "outputTokens": 12430,
    "totalTokens": 96640,
    "model": "claude-opus-4-7"
  },
  "identity": {
    "official_name":    { "value": "Acme Manufacturing Inc.", "confidence": 95 },
    "company_summary":  { "value": "Contract manufacturer of precision metal components for aerospace and defense OEMs.", "confidence": 88 },
    "industry_niche":   { "value": "Aerospace & Defense contract manufacturing", "confidence": 91 },
    "founding_year":    { "value": 1994, "confidence": 90 },
    "headquarters":     { "value": "Tulsa, Oklahoma", "confidence": 87 },
    "employee_count":   { "value": 340, "confidence": 72 },
    "company_size":     { "value": "Mid-market (100-500)", "confidence": 85 },
    "business_model":   { "value": "B2B contract manufacturing", "confidence": 93 }
  },
  "contact": {
    "primary_email":        { "value": "info@acmemfg.com", "confidence": 80 },
    "primary_phone":        { "value": "+1 (918) 555-0192", "confidence": 75 },
    "linkedin_company_url": { "value": "https://linkedin.com/company/acme-manufacturing", "confidence": 90 }
  },
  "people": {
    "ceo_name":         { "value": "Robert J. Walsh", "confidence": 82 },
    "ceo_linkedin_url": { "value": "https://linkedin.com/in/robertjwalsh", "confidence": 70 }
  },
  "indicators": {
    "Employee Headcount Size":    { "value": "Mid-market (100-500)", "confidence": 85 },
    "Primary GTM Motion":         { "value": "Direct Sales", "confidence": 80 },
    "Management Structure Type":  { "value": "Owner-operated", "confidence": 75 },
    "contact_availability":       { "value": "High", "confidence": 80 }
  },
  "thesis": {
    "thesis_fit_score":        { "value": 78, "confidence": 82 },
    "thesis_alignment":        { "value": "Good Fit", "confidence": 82 },
    "thesis_fit_justification": { "value": "Acme Manufacturing aligns well with the thesis: it operates in a regulated aerospace supply chain niche (matching the regulated-industry focus) and generates estimated $45M–$60M annual revenue within the target range. The B2B contract manufacturing model and direct-sales GTM motion fit the thesis criteria. The primary gap is the hardware/services nature vs. a preference for SaaS, which caps the fit score.", "confidence": 78 }
  },
  "insights": [
    { "field": "ISO Certification", "value": "ISO 9001:2015 certified since 2003", "source": "acmemfg.com/quality" },
    { "field": "Revenue Estimate", "value": "$45M–$60M annual revenue", "source": "industry report" }
  ]
}
curl example
curl https://api.acqwired.com/v1/task/47463e01-7f03-4065-998c-e36b63b9e2bd \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/research/{taskId}/reconstruct

Re-extract structured data from a completed task using a new schema — without re-running the full research pipeline. Reuses cached analysis from stages 1–6, only executes stage 7. Costs approximately 5% of the original task.

~95% cost savings

Changed your extraction schema after reviewing initial results? Reconstruct instead of re-queuing. The task retains the same taskId and updates in-place.

Request Body

schemaobject

New inline schema definition. Mutually exclusive with schema_id.

schema_idstring

ID of a saved schema to use for re-extraction. Mutually exclusive with schema.

Response — 202 Accepted
{
  "taskId": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Task reconstruction started - results will update when complete"
}
GET/tasks

List all tasks for your organization filtered by status bucket. Returns tasks newest-first. Use the nextPageToken from the response to paginate through additional results.

Session tasks are hidden by default

A task submitted with a session_id belongs to a journey — every task in a list-building or pipeline run does. Those are inspected through the sessions API, so this endpoint omits them unless you pass include_sessions=true. Every row carries sessionId (null when standalone), so the two are always distinguishable.

Two consequences worth knowing: GET /tasks and GET /tasks/counts will legitimately disagree (reconcile with include_sessions on either), and a page can come back with fewer than limit rows while hasMore is still true — page until hasMore is false rather than stopping on a short page.

Query Parameters

status"active" | "pending" | "completed" | "failed"

Status bucket to query. Defaults to "active". Active includes both queued and in-progress tasks.

include_sessionsboolean

Include tasks submitted with a session_id. Defaults to false, which lists standalone tasks only.

limitnumber

Maximum number of tasks per page. Defaults to 50, max 50.

nextPageTokenstring

Pagination cursor (unix timestamp ms) from the previous response. Omit for the first page.

Response — 200 OK

Response body
{
  "tasks": [
    {
      "taskId": "550e8400-e29b-41d4-a716-446655440000",
      "companyName": "Acme Manufacturing",
      "domain": "acmemfg.com",
      "question": "Is this a good PE target?",
      "status": "completed",
      "taskType": "lite",
      "sessionId": null,                          // submitted standalone
      "createdAt": "2026-02-20T14:30:00Z",
      "updatedAt": "2026-02-20T14:35:12Z",
      "errorMessage": null
    },
    {
      "taskId": "cf7e8d0f-29fe-48dd-816a-4b3ab9ff113b",
      "companyName": "CriticalCxE",
      "domain": "criticalcxe.com",
      "question": "Determine "Funding Stage" for this company",
      "status": "completed",
      "taskType": "lite",
      "sessionId": "shore-pues-rebuild-sep2026",  // only with include_sessions=true
      "createdAt": "2026-02-21T09:14:02Z",
      "updatedAt": "2026-02-21T09:15:38Z",
      "errorMessage": null
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextPageToken": "1740059400000"
  }
}
curl example
# standalone tasks only (default)
curl "https://api.acqwired.com/v1/tasks?status=completed&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

# everything, journey tasks included
curl "https://api.acqwired.com/v1/tasks?status=completed&include_sessions=true&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/tasks/counts

Per-status task counts for your organization, returning no task rows at all. Use this to answer 'how many' or 'is it done yet' — never a tally of GET /tasks pages, which cap at 50 rows each and will report 50 for an org with 70.

Query Parameters

include_sessionsboolean

Count tasks submitted with a session_id. Defaults to true — the honest total. Set false to get the number GET /tasks would list.

Response — 200 OK

Response body
{
  "pending": 0,
  "active": 2,
  "completed": 13887,
  "failed": 133,
  "total": 14022,
  "exact": false,                    // a partition hit the read cap — counts are FLOORS
  "includeSessionTasks": true,
  "note": "These are FLOORS, not totals — a status partition exceeded the read cap."
}

When exact is false, every number is a lower bound — read it as “at least”, not as a total.

curl example
curl "https://api.acqwired.com/v1/tasks/counts?include_sessions=false" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/schema/recommend

Generate AI-powered schema recommendations from natural language questions. Uses 11 PE/VC-optimized examples as few-shot context. Ideal for helping users choose the right field type and options.

Request Body

questionsstring[]required

Array of natural language questions (e.g. ["What is their competitive moat?"]).

Response body
{
  "schemas": [
    {
      "keyName": "CompetitiveMoat",
      "keyDescription": "Strength of the company's competitive advantage",
      "keyDataType": "categorical",
      "keyOptions": [
        "5 = Dominant moat",
        "4 = Strong moat",
        "3 = Moderate moat",
        "2 = Weak moat",
        "1 = No moat",
        "0 = Insufficient data"
      ]
    }
  ]
}
POST/schema/generate

Generate a schema definition from a natural language hint using AI, then automatically save it. Returns the schemaId for immediate use in research tasks. Ideal for one-click schema creation in workflows.

Request Body

hintstringrequired

Natural language description of what to extract (e.g. "funding stage of the company", "quality certifications held").

enumType"best" | "all" | "topN"

Result mode to apply if the AI generates a categorical schema. "best" (default) returns a single best match, "all" returns all matches, "topN" returns the top N.

enumTopNnumber

Number of results when enumType is "topN". Defaults to 3.

Response — 200 OK

Response body
{
  "schemaId": "schema_abc123",
  "name": "Funding Stage",
  "schema": {
    "keyName": "FundingStage",
    "keyDescription": "Current funding stage of the company",
    "keyDataType": "categorical",
    "keyOptions": [
      "Public",
      "Acquired — PE-backed",
      "VC-backed",
      "Angel-backed",
      "Bootstrapped / founder-owned"
    ],
    "enumType": "best"
  }
}
curl example
curl -X POST https://api.acqwired.com/v1/schema/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "hint": "funding stage of the company",
    "enumType": "best"
  }'
GET/schemas

List all saved schemas for your organization, ordered by creation date (newest first). Pass ?q= to prefix-search by field name (keyName) using the GSI2 index — no table scan.

Query Parameters

qstring

Prefix match on schema keyName (e.g. "ceo" matches "ceo_name"). Uses DynamoDB begins_with on GSI2 — fast indexed lookup, not a scan.

limitnumber

Maximum schemas per page. Defaults to 100.

nextPageTokenstring

Pagination cursor from the previous response. Omit for first page.

Response body
{
  "schemas": [
    {
      "schemaId": "schema_abc123",
      "name": "Acquisition Screening",
      "schema": { "keyName": "AcquisitionScore", "keyDataType": "categorical", ... },
      "createdAt": "2026-02-01T10:00:00Z",
      "createdBy": "user@firm.com"
    }
  ],
  "pagination": {
    "limit": 100,
    "nextPageToken": null
  }
}
curl — prefix search by keyName
curl "https://api.acqwired.com/v1/schemas?q=ceo" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/schemas/{schemaId}

Retrieve a single saved schema by ID.

schemaIdstringrequired

Schema identifier returned when the schema was created.

namestringrequired

Human-readable schema name.

schemaobjectrequired

Schema definition object.

createdAtISO 8601 stringrequired

Creation timestamp.

createdBystringrequired

Email of the user who created the schema.

POST/schemas

Create and save a new schema for reuse across research tasks. Reference the returned schemaId in future POST /research calls.

Request Body

namestringrequired

Human-readable name (e.g. "Acquisition Screening v2").

schema.keyNamestringrequired

Output field name.

schema.keyDescriptionstringrequired

What the field captures.

schema.keyDataType"categorical" | "string" | "number"required

Data type.

schema.keyOptionsstring[]

Required when keyDataType is "categorical". Ordered list of allowed values.

schema.enumType"best" | "all" | "topN"

Result mode for categorical schemas. Defaults to "best". See Result Mode in Schema Types.

schema.enumTopNnumber

How many results to return when enumType is "topN". Defaults to 3.

Response — 201 Created
{
  "schemaId": "schema_abc123",
  "name": "Acquisition Screening",
  "schema": { "keyName": "AcquisitionScore", ... }
}
PUT/schemas/{schemaId}

Update an existing schema. Partial updates supported — only include fields you want to change.

Request Body

namestring

New schema name.

schemaobject

Updated schema definition (replaces existing).

DELETE/schemas/{schemaId}

Permanently delete a saved schema. Existing research tasks that used this schema are unaffected.

Response — 200 OK
{ "message": "Schema deleted successfully" }
POST/evergreen/discover

Find companies by what their own website pages say - what they make, who they serve, who owns them - across 2.5M US companies whose sites were crawled. This is vector search over page text: the company name, domain and industry token are not matched at all. One call builds the whole result as a paged dataset and returns page 1; the same endpoint reads later pages.

A build reads the page index, ranks every company that matched, and takes under a minute, so it runs off the request. Shallow screens answer in the first call; deeper ones come back withstatus: "building"and a dataset_id to poll. Every page is written before the status flips to ready, so once a dataset is ready the pages can be fetched concurrently rather than in order.

Request Body

querystringrequired

What the company does, makes, sells, or is certified for, in plain words. Max 1000 characters. Keep geography and size out of it - those belong in filters, where they are exact. Omit when reading a page of an existing dataset.

dataset_idstring

Read a page of a dataset already built instead of building a new one. Pass it with page.

pagenumber

Which page of dataset_id to read. Default 1.

filtersobject

Exact-match filters: state, city, country, industry, tier, status, source_tier, employee_band, revenue_band, flags, year_founded, employee_min, employee_max. Each EXCLUDES companies whose value was never recorded rather than companies that fail the test, so a sparse filter shrinks the answer without saying so.

Response Fields

dataset_idstringrequired

Names the question it answers, e.g. k12_school_accounting_software_a7f3d. Use it to read further pages, snippets and full passages.

page / pages_total / totalnumberrequired

Where this page sits, how many pages there are, and how many companies the dataset holds.

rowsarrayrequired

One object per company: company_id, name, domain, city, state, country, industry, employee_band, revenue_band, status, signals, score (best text similarity), found_by (which phrasings found it). Rows are in merged order, not score order. No page text - see POST /evergreen/snippets.

phrasingsarray

Page 1 only. Per phrasing: query, rows (companies it found), full (it returned top_k, so there is more), only (companies no other phrasing found).

notestringrequired

Why rows carry no passage text, and which endpoint returns it.

nextstring

How to fetch the next page, in words, or null on the last one.

warningsarrayrequired

Page 1 only. Empty on a clean build; names a truncation or an empty result when there is one.

curl example
curl -X POST https://api.acqwired.com/v1/evergreen/discover \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "contract manufacturer of precision machined parts for aerospace and defense",
    "filters": { "state": "oh" }
  }'
Response - still building
{
  "dataset_id": "contract_manufacturer_of_precision_machined_parts_a7f3d",
  "status": "building",
  "query": "contract manufacturer of precision machined parts for aerospace and defense",
  "next": "The dataset is still being built. Call this again with that dataset_id and page 1 in about five seconds."
}
Response - a page
{
  "dataset_id": "contract_manufacturer_of_precision_machined_parts_a7f3d",
  "page": 1,
  "pages_total": 28,
  "total": 3012,
  "phrasings": [{ "query": "contract manufacturer of precision machined parts for aerospace and defense", "rows": 3000, "full": true, "only": 1830 }],
  "note": "Rows carry no passage text. A score means text SIMILAR to the query, not text that is TRUE of the company...",
  "next": "Page 1 of 28. For the next 53 companies call this again with page 2...",
  "rows": [
    {
      "company_id": "D:caseymachine.com",
      "name": "Casey Machine Co.",
      "domain": "caseymachine.com",
      "city": "lancaster",
      "state": "ny",
      "industry": ["manufacturing"],
      "employee_band": "11-50",
      "revenue_band": "$1m-$10m",
      "status": "active",
      "signals": ["is_founder_owned"],
      "score": 0.678
    }
  ],
  "warnings": []
}
GET/evergreen/discover/datasets

The screens this organization has run, newest first. Object storage answers 'give me page 4 of this id' and nothing else, so this is the only way to ask what datasets exist. Datasets are retained for 30 days.

Query Parameters

limitnumber

Datasets per page. Default 25, maximum 100.

cursorstring

The next_cursor value from a previous response.

Response body
{
  "datasets": [
    {
      "dataset_id": "k12_school_accounting_software_a7f3d",
      "query": "school district accounting software for K-12",
      "status": "ready",
      "total": 3012,
      "pages_total": 28,
      "source": "api",
      "created_at": "2026-09-13T10:04:11.000Z",
      "completed_at": "2026-09-13T10:05:06.000Z"
    }
  ],
  "next_cursor": null
}
POST/evergreen/snippets

Why those companies came back. Returns the passages that matched - up to five per company, each about 300 characters, with the section they came from and their own score. This is the screening step, and skipping it is how a blog post becomes a prospect.

A score means text similar to the query, not text that is true of the company. Asked for ISO 13485 certified manufacturers, the top result is a page titled "Why ISO 13485 Matters for Medical Device Manufacturers" - a blog post, scoring 0.765. Nothing but reading the passage separates it from a real manufacturer.

Request Body

dataset_idstringrequired

The dataset the companies came from.

company_idsarray

Up to 50 company ids from that dataset. An id the dataset does not hold comes back in missing rather than failing the call.

company_idstring

Or one, when checking a single company.

Response body
{
  "dataset_id": "iso_13485_certified_medical_device_contract_manufa_b2k91",
  "companies": [
    {
      "company_id": "D:www.frysteel.com",
      "name": "FRY STEEL COMPANY",
      "page": 1,
      "score": 0.765,
      "page_count": 1,
      "snippets": [
        {
          "key": "D:www.frysteel.com#certifications#0",
          "section": "certifications",
          "score": 0.765,
          "text": "Why ISO 13485 Matters for Medical Device Manufacturers. ISO 13485 offers a range of benefits..."
        }
      ]
    }
  ],
  "missing": []
}
POST/evergreen/pages

The full passages behind a match - up to 4,000 characters each, as embedded. Use /evergreen/snippets first when screening; come here when a snippet is genuinely ambiguous and you need the rest of what the page said.

Request Body

dataset_idstring

With company_ids: the page keys are resolved for you, so you never handle a vector key.

company_idsarray

Company ids from a dataset page. Used with dataset_id.

page_keysarray

The other way in: up to 100 keys taken verbatim from a page search. More than 100 is rejected rather than truncated.

GET/credits

Returns the credit balance for the organization associated with the authenticated API key. Returns 402 with remainingCredits: 0 when a research task is submitted and the balance is exhausted.

Response Fields

orgIdstringrequired

Organization ID the API key belongs to.

remainingCreditsnumberrequired

Credits remaining. Always 0 when isUnlimited is true.

totalCreditsUsednumberrequired

Cumulative credits consumed by this organization.

isUnlimitedbooleanrequired

When true, credits are not deducted per run. Balance is audited but not enforced.

lastUsedAtISO 8601 string

Timestamp of the most recent enrichment run.

lastTopUpDateISO 8601 string

Timestamp of the most recent credit top-up.

Response body
{
  "orgId": "46805989-52b6-4ce4-b68b-4cb1e541912b",
  "remainingCredits": 500,
  "totalCreditsUsed": 1234,
  "isUnlimited": false,
  "lastUsedAt": "2026-05-25T10:00:00.000Z",
  "lastTopUpDate": "2026-05-20T09:00:00.000Z"
}
curl example
curl https://api.acqwired.com/v1/credits \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/health

Health check endpoint. Returns 200 with no authentication required. Use for uptime monitoring.

Response — 200 OK
{
  "status": "healthy",
  "service": "evergreen-api-public-gateway",
  "timestamp": "2026-02-26T00:00:00.000Z"
}

Schema Types

Three field types cover 100% of PE data enrichment needs. All types are extracted at temperature 0.0 for deterministic, consistent output across every task.

categorical— ordinal scales or named option sets

Use for scoring, grading, and classification. Define a fixed list of options — the pipeline selects the best match. Supports both ordinal 0–5 scales and named option sets (funding stage, business model, ownership type).

Ordinal scale example
{
  "keyName": "CompetitiveMoat",
  "keyDataType": "categorical",
  "keyOptions": [
    "5 = Dominant moat",
    "4 = Strong moat",
    "3 = Moderate moat",
    "2 = Weak moat",
    "1 = No moat",
    "0 = Insufficient data"
  ]
}
Named options example
{
  "keyName": "FundingStage",
  "keyDataType": "categorical",
  "keyOptions": [
    "Public",
    "Acquired — PE-backed",
    "VC-backed",
    "Angel-backed",
    "Bootstrapped / founder-owned"
  ]
}
string— free text or semicolon-delimited lists

Use for descriptions, multi-value lists (certifications, customers, investors), and narrative fields. For multiple values, the pipeline returns semicolon-delimited output.

Delimited list example
// Input schema
{ "keyName": "Certifications", "keyDataType": "string", "keyDescription": "Quality certifications held" }

// Example output
"ISO-13485; AS-9100; IPC-A-610; ITAR"
Free text example
// Input schema
{ "keyName": "BusinessDescription", "keyDataType": "string", "keyDescription": "One-sentence business description" }

// Example output
"Enterprise AI platform for financial services serving 200+ institutional clients"
number— quantitative metrics

Use for headcount, revenue estimates, founding year, office count, and other numeric metrics extractable from public web content.

Number example
// Input schema
{ "keyName": "EstimatedHeadcount", "keyDataType": "number", "keyDescription": "Approximate number of employees" }

// Example outputs
342        // headcount
15000000   // revenue in dollars
1994       // founding year
enumType— result mode for categorical schemas

For categorical schemas, the enumType field controls how the AI returns matched options. Set it on inline schemas, saved schemas, or the generate endpoint.

best

Best match (default)

Returns a single highest-confidence option. Use for scoring scales and exclusive classifications.

all

All matches

Returns all matching options as a comma-separated string. Use when multiple categories may apply (e.g. certifications, industries).

topN

Top N matches

Returns the N most relevant options ordered by confidence. Pair with enumTopN (default: 3).

Top N example — returns top 3 certifications
{
  "keyName": "TopCertifications",
  "keyDataType": "categorical",
  "keyOptions": ["ISO 9001", "ISO 13485", "AS9100", "ITAR", "IPC-A-610", "NADCAP"],
  "enumType": "topN",
  "enumTopN": 3
}

// Example output: "ISO 9001, ITAR, AS9100"

Research Pipeline

Each research task executes in an isolated ECS Fargate container with a 9-minute timeout. The pipeline runs 7 sequential stages, with some stages executing sub-agents in parallel.

01

Query Decomposition

Breaks the research question into typed subtopics (company analysis, competitive intelligence, leadership, financial). Routes each to the optimal path: basic (fast factual lookup) or deep (multi-source analysis).

02

Strategic Web Search

Executes web searches to identify authoritative sources. Scores each URL by relevance (1–5 scale). Basic subtopics complete here; complex subtopics advance to planning.

03

Content Extraction

Scrapes high-priority URLs in parallel batches. Content over 3,000 characters is auto-summarized. All source content is merged into a unified knowledge base.

04

Multi-Agent Analysis

Four specialized agents collaborate: Analyst extracts insights, Writer drafts narrative, Reviewer quality-checks, Reviser improves based on feedback. Each subtopic produces a verified analysis.

05

Claim Verification

Findings are cross-referenced against cited sources. A confidence score (0–100) is computed for the overall output. Verified claims are formatted for the claims output field.

06

Report Generation (optional)

If generateReport=true, a comprehensive markdown report synthesizes all subtopic findings, with sources cited and confidence score. Skipped otherwise to reduce cost.

07

Structured Extraction

Your schema fields are extracted from the research output at temperature 0.0. Uses prompt engineering with Handlebars templates and JSON Schema validation for strict, deterministic output.

Error Codes

All errors return a JSON body with a message field describing the issue.

StatusMeaningCommon Cause
400Bad RequestMissing required fields, invalid schema definition, or malformed JSON.
401UnauthorizedMissing or invalid Authorization header. Check your API key.
402Payment RequiredCredit balance is exhausted. Top up via the dashboard to continue.
403ForbiddenAPI key is valid but lacks permission for the requested operation.
404Not FoundtaskId or schemaId does not exist in your organization.
409ConflictTask is not in a state that allows the requested operation (e.g. reconstruct on an in-progress task).
429Rate LimitedToo many concurrent research tasks. Queue additional tasks after existing ones complete.
500Internal Server ErrorPipeline execution error. The task status will be set to "failed" with an errorMessage.

Error response shape

{
  "message": "Missing required field: company_name",
  "statusCode": 400
}