---
title: "Generate a legacy + Temporal tree pair for A/B comparison (internal admin tool)"
method: POST
path: "/context-documents/tree/compare"
tags: ["Context Documents"]
---

# Generate a legacy + Temporal tree pair for A/B comparison (internal admin tool)

`POST /context-documents/tree/compare`

Kick off both the legacy BackgroundTask path AND the Temporal
workflow against the same app data, in a single call.

Admin-only — used by Hyperspell employees to validate Temporal-vs-legacy
parity. Reads (and emits via the GET diff endpoint) both engines' raw
metadata, including doc_manifests and source_manifest. Will be deleted
once the Temporal cutover is complete; no public-API stability promise.

Wraps the dispatch logic the comparison UI was previously doing from
the browser (two separate POSTs to /tree and /tree-temporal). This
endpoint guarantees both rows are created with identical request
inputs, in a single DB transaction, before any dispatch happens — so
a script or eval framework can run the comparison without needing a
browser.

The legacy side dispatches synchronously into a FastAPI BackgroundTask
(fire-and-forget, can't fail at dispatch). The Temporal side dispatches
via `_start_tree_workflow` (gRPC; can fail in three ways: known
ALREADY_EXISTS, ambiguous RPCError, or anything unexpected). All three
failure modes mark the temporal row FAILED via the orphan-cleanup
helper and let the legacy run continue — the endpoint always returns
200 with both tree_ids so the caller's polling loop sees a terminal
state on the failed side.

## Request body

- TreeGenerateRequest — Request body for POST /context-documents/tree.
  - `sources` string[], nullable — Integration sources to include (e.g., ['gmail', 'slack']). Defaults to all.
  - `user_id` string, nullable — User ID for personal tier scoping. When set, personal/context.md is generated from this user's data only. Company and workstream tiers still use all data.
  - `workstream_name` string, nullable — Generate docs for this workstream only (skip auto-detection).

## Response `200`

Successful Response

- TreeCompareResponse — Response shape for POST /context-documents/tree/compare. Returns both tree_ids the request created, one per generation path. Either may end up FAILED — the comparison UI / caller polls each via `GET /context-documents/tree/{tree_id}/progress` to see how each side runs to completion.
  - `legacy` TreeGenerateResponse, required
    - `tree_id` string, required
    - `status` string, required
    - `created_at` string, date-time, required
  - `temporal` TreeGenerateResponse, required
    - `tree_id` string, required
    - `status` string, required
    - `created_at` string, date-time, required

## Other responses

- `422` — Validation Error

## Changes

- **2026-05-05** `023174b0253c` — 1 info
  - the endpoint scheme security `AsUser` was removed from the API
- **2026-04-25** `b79d6d7c41fc` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/hyperspell/apis/hyperspell-api/changes/context-documents/tree/compare/post.md)

---

[API](https://skmtc.dev/hyperspell/apis/hyperspell-api.md) · [All operations](https://skmtc.dev/hyperspell/apis/hyperspell-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/hyperspell/hyperspell-api/revisions/023174b0253c/schema)
