Export

Export research results as HTML, PDF, Markdown, DOCX, slides, run records, or evidence packs

Research results can be exported in seven formats via the /results/\{result_id\}/export endpoint.

Formats

FormatContent-TypeUse Case
htmltext/htmlBrowser viewing, embedding, sharing
pdfapplication/pdfDownload, print, archive
markdowntext/markdownRaw content, further processing
docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.documentEditable Word document
slidestext/htmlSelf-contained reveal.js presentation deck
run-recordapplication/jsonShared run record and explicit unassessed claims
evidence-packapplication/zipUnsigned evidence archive with offline verification

Usage

HTML Export

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=html"

Supports a theme parameter for light or dark mode:

# Dark theme
curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=html&theme=dark"

The HTML export is a self-contained page with:

  • Full markdown-to-HTML rendering
  • Styled headings, tables, lists, code blocks
  • Source list with URLs and source types
  • Research metadata (query, mode, duration)

PDF Export

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=pdf" \
  -o report.pdf

The PDF includes:

  • Title and metadata header
  • Full report content with formatting
  • Sources appendix with URLs and source types
  • Generated via fpdf2 with HTML subset rendering
  • Fallback to plain text if HTML rendering fails

Markdown Export

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=markdown" \
  -o report.md

Returns the raw markdown report as generated by the synthesis model. This is the most portable format for further processing.

DOCX Export

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=docx" \
  -o report.docx

Returns an editable Microsoft Word document with the title, metadata, formatted report body, and a sources appendix.

Slides Export

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=slides" \
  -o report-slides.html

Returns a self-contained reveal.js HTML deck that turns the report into a presentation. Open it in any browser — no build step required. Long sections are split across continuation slides automatically.

Parameters

ParameterTypeDefaultOptions
formatstring"html"html, pdf, markdown, docx, slides, run-record, evidence-pack
themestring"light"light, dark (HTML only)

Filenames

Downloaded files use a sanitized version of the research query as the filename:

  • what-is-the-current-state-of-ai-agents.pdf
  • what-is-the-current-state-of-ai-agents.md
  • what-is-the-current-state-of-ai-agents.docx
  • what-is-the-current-state-of-ai-agents-slides.html

HTML and slides exports use Content-Disposition: inline (displayed in browser). PDF, Markdown, and DOCX use Content-Disposition: attachment (downloaded).

Getting a Result ID

Result IDs are returned in the result SSE event during research, and can be retrieved from:

# List all results
curl -H "X-API-Key: your-key" https://api.krawl.sh/results

# Get a specific result
curl -H "X-API-Key: your-key" https://api.krawl.sh/results/RESULT_UUID

Evidence time and access

Research sources carry optional retrieved_at (UTC), published_date, updated_date, date provenance, access_status, source_record_id and temporal_status. Missing fields on older reports mean unknown; never assign export time as retrieval time. Access states are inspected_text, partial_excerpt, provider_summary, metadata_only, fetch_failed, or unknown. These describe available evidence, not claim support or truth. A recent fetch does not make an old article current. Summary/metadata-only results do not establish that the original text was read.

Optional source_policy.as_of sets a UTC evidence cutoff; dates after it are quarantined in quarantined_sources, outside synthesis. Without it the cutoff is research start. This is not a historical web archive; undated content remains uncertain. See evidence methodology.

Evidence coverage

The optional evidence_coverage result field gives descriptive counts of unique exact URLs discovered, explicitly fetched, retained, referenced in outgoing model input, and cited. Stages overlap: a retained search snippet may never have had its original page fetched. It also reports explicit failed/unavailable fetches, unknown fetch/access states, retained-host concentration, missing publication dates and their known range. A model-input reference may contain only metadata or a short excerpt; a citation is not a support verdict.

These counts do not establish representative sampling or correct selection bias. Hostnames do not prove independent origins; mirrors may share a publisher. Old reports without this field have unknown coverage. No extra LLM call is made; the measured instrumentation overhead is reported as measurement_overhead_ms, not a guarantee of zero added latency. See evidence methodology.

Run record

Download /results/{result_id}/export?format=run-record with the owning API key. The JSON bundle uses schema version 1 and includes the run, claim candidates, source observations, a report snapshot, and the original Markdown. It is compatible with the shared Claude Code run-record schemas. Every hosted claim starts unassessed; this export does not judge support or reconstruct saved page bytes. Empty events and ledger arrays mean those details were not retained, not that the run was free. Legacy observation dates remain unknown.

MCP export_result accepts the same format and returns JSON text inline. The read-only export does not add storage or make ZDR runs retrievable.

Schemas: bundle. From the repository, validate a downloaded bundle offline:

uv run --project apps/api --locked python scripts/validate_run_record.py report-run-record.json

Evidence pack

Use format=evidence-pack to download an unsigned ZIP with a versioned manifest, the run record, and instructions for offline verification. The manifest binds exact stored bytes with SHA-256. It preserves source access states and observation times; an export timestamp is never substituted for a missing retrieval time. Hosted results have no retained raw page copies, so those copies are explicitly unverifiable. An export does not fetch them.

curl -H "X-API-Key: your-key" \
  "https://api.krawl.sh/results/RESULT_UUID/export?format=evidence-pack" \
  -D export-headers.txt -o report.evidence.zip

The owning key is required for retained results. Wrong-owner and deleted results return 404. The response is application/zip, with Cache-Control: private, no-store and X-Krawl-Evidence-SHA256. Keep private packs private. This operation creates no retained server-side archive or new source copy.

Current research SSE and MCP results include their server-allocated id, query, mode, created_at and measured duration_seconds. The ID identifies the logical result; it is not proof of persistence for a ZDR or failed-save run. Cutoff and quarantined source observations are preserved in inline exports.

For a streamed result, including a ZDR result, send the full public result object in {"result": ...} to POST /exports/evidence-pack. It must include id, query, mode, report (or markdown), sources, created_at and duration_seconds. The request body is limited to 1 MiB. The server projects only public result fields and builds the archive in memory; it never stores the query, content, source URL hashes, archive, or idempotency response. It sends no webhook and makes no model or source-provider call. You may save the returned archive on your own device. Supplying an object does not authenticate its origin or assertions.

MCP export_result accepts format: "evidence-pack" and exactly one of result_id or result. The ZIP is returned in content_base64, with sha256, manifest_sha256, size_bytes, unavailable_copies, and unsigned: true. Other export formats continue to use a retained result_id.

Verify offline

From a checkout, install the independent core and run:

uv run --package krawl-core krawl-evidence verify report.evidence.zip
# Optionally pin a digest obtained through a trusted channel:
uv run --package krawl-core krawl-evidence verify report.evidence.zip --sha256 DIGEST

The verifier has no API credentials or network requirement and extracts no files. Exit 0 means the declared bytes, internal references and available cited passages match. Exit 2 means some source copies are unavailable; the output identifies each source and report version. Exit 1 means invalid bytes, metadata, references, passage offsets or archive structure. These codes do not measure factual correctness, source independence or publisher identity. An attacker who can replace the entire unsigned archive can replace its hashes. A trusted external digest detects replacement of the whole archive.

For local Claude Code runs, the workbench's Download evidence pack includes all report versions and already saved copies. The command-line equivalent is:

uv run --package krawl-core --extra engine krawl-engine export \
  --project /path/to/project --output report.evidence.zip

The CLI creates a new private file (0600); it refuses to overwrite a file. Missing local captures remain explicitly unverifiable. The export preserves existing retention choices and does not acquire new rights to redistribute a source. Use only copies you are entitled to retain and share.

Manifest schema. The format is version 1: SHA-256 over exact raw bytes and UTF-8 extracted text; json-utf8-sort-v1 encodes JSON with sorted keys, compact separators, unescaped Unicode, no non-finite numbers, and one trailing newline. Passage offsets count Unicode code points in the extracted text. The verifier rejects duplicate JSON keys, traversal, symlinks, unexpected members, and oversized archives (64 MiB content, 1 MiB manifest, 4,096 entries). It supports stored and deflated ZIP members without extracting them.

Signed origin attestations are future work. They would require defined issuer identity and claim semantics, trusted roots, signing-key custody and rotation, revocation and compromise handling, and client verification policy. This unsigned format provides none of those assurances.

On this page