# Share a LlamaIndex Workflow's Output — Publish From a Step

Canonical: https://commareports.com/agents/share-llamaindex-output
Published: 2026-09-14

> A LlamaIndex workflow ends with a StopEvent holding a report nobody can open. Publish from the final step and return a URL — plus the citations that justify it.

# Share what a LlamaIndex workflow produced

A workflow retrieves, re-ranks, synthesizes and writes. The last step emits a
`StopEvent` carrying a finished document — an evidence summary, a due-diligence
memo, a literature review with citations.

`handler` resolves. The result is in memory. The analyst who commissioned it
gets a paste into Slack that loses the formatting and every source link.

## Publish in the stopping step

Workflows are event-driven and explicit, so publication is a normal step
concern:

```python
class ReportWorkflow(Workflow):
    @step
    async def finalize(self, ev: DraftEvent) -> StopEvent:
        html = render(ev.sections, ev.citations)
        r = httpx.post(
            "https://commareports.com/api/v1/reports",
            headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
            json={"title": ev.title, "html": html},
        )
        r.raise_for_status()
        return StopEvent(result={"url": r.json()["url"], "id": r.json()["id"]})
```

The result is now two short strings. Anything downstream — a Slack notifier, a
ticket comment, a calling workflow — handles an address instead of a document.

## RAG output needs its sources visible

This is the part specific to LlamaIndex. A retrieval-backed answer is worth
exactly as much as its citations, and citations survive badly in chat: links
get flattened, node text gets truncated, and the reader is asked to trust a
paragraph with a bracket number pointing nowhere.

A rendered page keeps them. Put each claim next to the passage it came from,
keep the source metadata in the markup, and the reviewer can check the
reasoning instead of accepting it. When they disagree, the comment lands on
that paragraph rather than arriving as "the third point seems off" — see
[commenting on HTML](/comment-on-html).

## Update, don't re-publish

Agent workflows iterate. If yours refines an answer over several passes, keep
the report id from the first publish and update it:

```python
httpx.patch(
    f"https://commareports.com/api/v1/reports/{report_id}",
    headers={"Authorization": f"Bearer {token}"},
    json={"html": improved_html},
)
```

One address, one comment history, and a link that keeps working after you
shared it. The alternative is a reviewer commenting carefully on revision two
while everyone else reads revision four.

## Worth knowing

- **Deployed workflows have no reachable filesystem.** Writing `report.html`
  in a LlamaCloud deployment or a container produces nothing — the same
  problem as [publishing from CI](/ci).
- **Do not carry HTML through the event stream.** Pass the URL between steps;
  the document does not need to travel.
- **`reports:write` to publish, `comments:read` to act on feedback** — see
  [scoped tokens for AI agents](/agents/scoped-tokens-for-ai-agents).
- **5 MB per report body.**

## Try it

Free — unlimited reports, commenters and revisions.

**[Read the API reference →](/docs/api)**

### Related

- [Where should my agent post?](/agents/where-should-my-agent-post) ·
  [Share a deep research report](/agents/share-deep-research-report)
- [Share a LangGraph run's output](/agents/share-langgraph-output) ·
  [Share a PydanticAI agent's output](/agents/share-pydantic-ai-output)
- [The API](/docs/api) · [Commenting on HTML](/comment-on-html)
