---
title: Tutorial: Company Intelligence Workflow
description: Build, publish, and integrate a workflow that turns a company website into a structured sales-research brief.
source: https://www.edgaze.ai/docs/builder/tutorial-company-intelligence
section: builder
---
# Tutorial: Company Intelligence Workflow

> Build, publish, and integrate a workflow that turns a company website into a structured sales-research brief.

**Audience: Creators building and publishing workflows.**

## What you will build

This workflow accepts a company name, public website URL, and research goal. It retrieves the public page, asks an LLM to produce a concise evidence-aware company brief, and returns a reusable Markdown report.

The result is commercially useful for account research, sales preparation, partner screening, and market mapping. It is still an AI-generated research aid: users must verify claims against primary sources before relying on them.

## Prerequisites

- An Edgaze account with access to Workflow Studio.
- A public HTTPS company page that permits automated retrieval.
- A valid provider route for the selected LLM model. Review [API Vault](/docs/builder/api-vault) and disclose the listing's credential mode.
- For API integration, an API key with `run:read` and `run:execute`.
- For completion notifications, an HTTPS webhook endpoint and its Edgaze signing secret.

## 1. Create the workflow

Open **Workflow Studio**, choose **New workflow**, and name it `Company Intelligence Brief`.

Add these blocks in order:

1. **Workflow Input** named `Company name`, type `Text`, required.
2. **Workflow Input** named `Website URL`, type `URL`, required.
3. **Workflow Input** named `Research goal`, type `Long Text`, optional, with a default such as `Sales discovery and account planning`.
4. **HTTP Request** configured for `GET`.
5. **LLM Chat** configured to produce the brief.
6. **Workflow Output** named `Company intelligence brief`.

The public input schema is generated from the input blocks. Keep their names stable after customers or API clients start using the workflow. API callers may use an input's exact `name` or its `nodeId`, but node IDs are safer when names may change.

## 2. Configure website retrieval

Connect **Website URL** to **HTTP Request**. Set:

- **Method:** `GET`
- **Follow Redirects:** enabled
- **Allowed Hosts:** the company domain when building for one known source; otherwise leave this unset only when the product genuinely accepts arbitrary public sites
- **Credentials:** `None`

Do not send secrets in the URL. Private IP ranges, internal hosts, unsafe redirects, and destinations rejected by Edgaze network policy will fail the block. A non-2xx HTTP response follows the block's Error output; DNS, policy, network, and timeout failures fail the block.

## 3. Configure analysis

Connect the HTTP Request Success output to **LLM Chat**. Use instructions like:

```text
Create a company intelligence brief from the retrieved public webpage.

Return Markdown with:
1. company summary
2. products and target customers
3. likely business priorities
4. three evidence-backed sales hypotheses
5. open questions and verification risks

Distinguish facts present in the source from inference. Do not invent revenue,
headcount, customers, funding, or contact details. Use the supplied company name
and research goal as context.
```

Reference the connected company name and research goal using the block connections or the variable controls shown by Workflow Studio. Keep the retrieved page as the model input and the instructions in the LLM prompt. Choose a current model from the inspector and set **Max Tokens** close to the expected report length.

Connect the LLM response to **Workflow Output**. Keep the native Markdown text; the output renderer selects the appropriate presentation automatically.

## 4. Test realistic and failure cases

Use **Run** in Workflow Studio with:

```json
{
  "Company name": "Example Corp",
  "Website URL": "https://example.com",
  "Research goal": "Prepare for a first sales discovery call"
}
```

Verify all of the following before publishing:

- The HTTP block retrieves only the expected public destination.
- The report separates sourced facts from inference.
- Missing required inputs are rejected.
- A malformed URL is rejected.
- A blocked, timed-out, or non-2xx destination produces an understandable failure.
- The output has no raw credentials, internal block data, or unsupported certainty.

Ordinary failed and cancelled runs do not charge creator margin. A compute-limit stop is a distinct outcome where already consumed compute may remain charged. See [When Runs Fail](/docs/billing/when-runs-fail).

## 5. Review compute and set margin

Open the publishing flow and review **Estimated compute** using realistic input sizes. The estimate informs the buyer's displayed price; it is not deducted from creator earnings.

For a paid workflow, set a creator margin within the current limits shown in [Pricing Limits](/docs/pricing-limits). The buyer sees one displayed per-run price containing hosted compute plus creator margin. On a successful run, the creator earns 80% of the margin.

If the listing uses runner-managed provider keys, verify the BYOK requirements and pricing in [BYOK](/docs/billing/byok). Disclose required providers on the listing.

## 6. Publish and run from the marketplace

Add an accurate title, description, example output, credential disclosure, and limitations. Publish an immutable version, then open its marketplace product page.

Run it once as a buyer would:

1. Confirm the displayed price before funding.
2. Supply all required inputs.
3. Start the run.
4. Review the final report and wallet or bundle history.

Successful wallet runs charge the displayed price. A matching workflow bundle is selected before wallet funding. The full funding contract is in [Create Run](/docs/api/create-run#canonical-funding-and-acceptance-behavior).

## 7. Run through the API

Fetch the workflow first and build inputs from its actual `inputSchema`. Replace the example UUIDs and input keys below with the values returned for your published workflow.

```bash
curl --request POST "https://www.edgaze.ai/api/v1/runs" \
  --header "Authorization: Bearer $EDGAZE_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: company-example-corp-2026-07-30" \
  --data '{
    "workflow": "550e8400-e29b-41d4-a716-446655440000",
    "inputs": {
      "Company name": "Example Corp",
      "Website URL": "https://example.com",
      "Research goal": "Prepare for a first sales discovery call"
    }
  }'
```

The response is `202 Accepted` with `statusUrl`, `eventsUrl`, and `streamUrl`. Store the run id and idempotency key together. Reusing the same key and request returns the original run; changing workflow, normalized inputs, or requested version returns `409 idempotency_conflict`.

## 8. Poll or stream progress

For a simple server integration, poll no more than once per second and back off:

```javascript
const terminal = new Set(["completed", "failed", "cancelled"]);
let delayMs = 1000;

while (true) {
  const response = await fetch(statusUrl, {
    headers: { Authorization: `Bearer ${process.env.EDGAZE_API_KEY}` },
  });
  if (!response.ok) throw new Error(`Run read failed: ${response.status}`);
  const body = await response.json();
  if (terminal.has(body.status)) {
    console.log(body.outputs);
    break;
  }
  await new Promise((resolve) => setTimeout(resolve, delayMs));
  delayMs = Math.min(Math.round(delayMs * 1.6), 10000);
}
```

For a live UI, connect to `streamUrl` as Server-Sent Events. Persist each event `sequence` and resume with `Last-Event-ID`. Append `data.text` from `node.output.delta` events in sequence order. See [Streaming](/docs/api/streaming).

## 9. Receive completion through a webhook

Create a webhook subscription in the developer dashboard for `run.completed`, `run.failed`, and `run.cancelled`. Verify the signature against the raw request body before parsing JSON. Return a 2xx response only after your receiver has durably recorded the event.

Webhook deliveries are single-attempt and are not automatically retried. Reconcile missed notifications by reading the run endpoint. Use the complete verifier in [Webhooks](/docs/api/webhooks).

## 10. Verify output and billing

After a terminal response:

- Confirm `status`, `reason`, and `outputs`.
- Confirm `billingStatus` is final rather than `pending`.
- Compare `displayedChargeUsd` with wallet history or the bundle counter.
- On success, confirm creator earnings were recorded at 80% of margin.
- On ordinary failure or cancellation, confirm `billingStatus` becomes `not_charged` and no creator earnings appear.
- If the run stopped at the compute limit, review the separately labeled partial-compute outcome.

You now have one workflow that is testable in Workflow Studio, saleable in the marketplace, and integrable through polling, SSE, and signed webhooks.
