> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Saved answers

> Keep the exact answer a reader inspected as a dataset version, from an app or the CLI

A query answer is computed when someone asks. To keep the exact answer a reader
inspected, as a dataset version other systems read, declare a query dataset and
save the answer through a reviewed request.

## Declare a query dataset

Declare the dataset from its complete query. The native analyzer derives its
columns, nullability, logical formats and source set; code generation commits
its field identities. There is no second row schema to maintain.

```ts bijection/datasets.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { defineDataset } from "@bijection/datasets";
import { regionalSales } from "./analytics";

export const report = defineDataset({ key: "report", source: regionalSales });
```

## Expose the save operation

Expose the save operation with its capability. The dataset keys and each public
route are explicit; module or export names do not select a save owner. For a
component installed as `datasets`, its root publishing module includes:

```ts bijection/features/datasets.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { expose } from "bijection/server";
import { makeFunctionReference } from "bijection/server";
import { components } from "../_generated/api";

// This module also exports the authenticated datasetsApplication readers.
export const saveAnswer = expose(components.datasets.transfers.saveAnswer, {
  datasetSave: {
    datasets: ["report"],
    reservation: makeFunctionReference("features/datasets:beginUpload"),
    preparation: makeFunctionReference("features/datasets:keepAnswer"),
    publication: makeFunctionReference("features/datasets:uploadStatus"),
  },
});
```

Admission checks these routes against their public calling contracts and
requires each key to name a dataset kept from answers. The containing
application supplies membership and row authorization through its ordinary
dataset readers.

## Save from your app

The generated workspace binds its question, operation and dataset clients from
the admitted program. Configure the deployment, sign-in and request storage
once. Browsers use tab custody; Node uses
`fileRequests(directory, { deployment: url, namespace: user.id })` from
`bijection/node` in the same `requests` option for answers and operations.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { createWorkspace } from "./bijection/_generated/client";

const workspace = createWorkspace({
  url: deploymentUrl,
  token: getAccessToken,
});
const execution = await workspace.queries.analytics.regionalSales.create({
  region: "EU",
});
const displayedAnswer = await execution.result();
const request = await workspace.datasets.datasets.report.prepareSave(displayedAnswer);
const proposed = await request.propose();
if (proposed.kind === "proposed") {
  // Display the exact proposal and submit it when the reader accepts it.
  const submission = await request.submit({
    proposal_id: proposed.proposal.ref.proposal_id,
  });
  if (submission.kind === "accepted") {
    const publication = await request.followPublication();
    if (publication.kind === "published") {
      console.log(publication.version.version_id, publication.version.storage);
    }
  }
}
```

An **execution** owns one answer's retained lifecycle. An **answer** owns
immutable results and their read capabilities. Its `reference` is serializable
metadata for a complete validated result. A **request** owns one immutable
intention and its proposals. Local **acceptance** names an upload; **publication**
records that upload's exact version. Acceptance alone never means the version
exists.

Retain `request.ref` and restore with
`await workspace.datasets.datasets.report.restoreSave(ref)`. `followPublication()`
recovers that original request, then observes its exact accepted upload. It does
not choose the newest dataset version, create another request or ask the
sources again.

`submission.kind` distinguishes `accepted`, `refused`, `attempt_failed` and
`acceptance_unknown`. An unknown acceptance remains unknown until recovery finds
its decision. If recovery reports `absent`, `request.submit()` explicitly
submits that same request. Ending a client wait leaves accepted server work
recoverable.

The client's request journal retains preparation before contacting the server. A
lost reply reuses the original slot and kept file. Saving sends no browser row
array. A file already kept for that slot remains recoverable after the original
answer expires; current authorization and erasure rules still apply.

## Save from the CLI

The CLI uses the same public calls and its ordinary request journal:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection dataset save-answer submit report --answer ANSWER_ID --request-id save_report
# Inspect the returned review, then submit that original review:
bijection dataset save-answer submit report --request-id save_report --confirm
bijection dataset save-answer status report --request-id save_report --wait 30s --format json
```

After an interrupted reply, reuse the original request key. Confirmation and
status need no answer ID or current feature lookup: the retained request owns
its original preparation and capability. An ended status wait preserves that
request. When multiple save owners match, select the exact public reference
with `--operation`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.