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

# Handle ParaLens API Versioning and Schema Evolution

> Learn how ParaLens versions the TxReport schema and how to write resilient clients that handle new intent kinds, motif types, and field additions.

ParaLens uses a `schema_version` integer at the top of every `TxReport`. Currently `1`. Clients should read this field and follow the guidance on this page to build integrations that continue working as the API evolves.

## schema\_version

Every `TxReport` includes `schema_version` as its first field:

```json theme={null}
{
  "schema_version": 1,
  ...
}
```

Check this value before parsing:

```ts theme={null}
const report = await analyze(txHash);

if (report.schema_version !== 1) {
  console.warn(`Unexpected schema version: ${report.schema_version}`);
  // Fall back to a minimal display or prompt the user to refresh
}
```

A bump to `schema_version` signals a **breaking** structural change to the response shape. Additive changes (new fields, new enum values) do **not** bump the version.

## Additive vs. Breaking Changes

<CardGroup cols={2}>
  <Card title="Additive (non-breaking)" icon="circle-plus">
    These changes will not break well-written clients and will **not** bump `schema_version`:

    * New top-level fields in `TxReport`
    * New `intent_kind` values
    * New `motif.kind` values
    * New `economics.warnings` string values
    * New `position_effects.effect` or `.kind` values
    * New optional sub-fields in any object
  </Card>

  <Card title="Breaking (version bump)" icon="triangle-exclamation">
    These changes **will** bump `schema_version`:

    * Removed fields
    * Renamed fields
    * Changed field types
    * Changed response shape at the top level
    * Removed enum values your code may depend on
  </Card>
</CardGroup>

## Client Resilience Rules

Follow these rules to write a client that degrades gracefully rather than breaking on additive changes:

<Steps>
  <Step title="Check schema_version on startup">
    Read and validate `schema_version` as the first step in your parsing logic. Log or alert when it changes.
  </Step>

  <Step title="Treat unknown intent_kind as UnknownComplexFlow">
    Never throw on an unrecognized `intent_kind`. Always provide a fallback:

    ```ts theme={null}
    function getLayout(intentKind: string) {
      return layoutMap[intentKind] ?? 'fallback';
    }
    ```

    See [Dashboard Layouts](/docs/guides/dashboard-layouts) for a full layout switch.
  </Step>

  <Step title="Treat unknown motif.kind as opaque">
    Motif kinds are structural evidence labels. If you encounter an unknown kind, skip it or show it as a raw label — do not fail.
  </Step>

  <Step title="Treat missing optional fields as null/undefined">
    Many fields are optional. Accessing `report.classification.actor` may return `null`. Use optional chaining or null checks throughout.

    ```ts theme={null}
    const actor = report.classification?.actor ?? report.tx.signer;
    ```
  </Step>

  <Step title="Never hard-fail on unknown warning strings">
    `economics.warnings` is a string array. New warning codes may be added. Handle known warnings explicitly and log or ignore the rest.

    ```ts theme={null}
    for (const warning of report.economics.warnings) {
      if (warning === 'IntentActorDiffersFromSigner') {
        showActorWarning();
      } else {
        console.info('[ParaLens] Unknown warning:', warning);
      }
    }
    ```
  </Step>

  <Step title="Always check DisplayMoney.available">
    Any field using the `DisplayMoney` shape (`fee_usd`, `net_usd_before_gas`, etc.) may have `available: false`. Never render the `text` value without checking first.

    ```ts theme={null}
    function renderMoney(money: DisplayMoney): string {
      return money.available ? money.text : money.reason ?? '—';
    }
    ```
  </Step>
</Steps>

## TypeScript Type Safety

Avoid strict union types for `intent_kind` in your client — this causes TypeScript errors when new values appear:

```ts theme={null}
// ❌ Breaks when a new intent_kind is added
type IntentKind = 'Swap' | 'AggregatedSwap' | 'Arbitrage';

// ✅ Accepts any value; document known values in a comment
type IntentKind = string; // Known values: 'Swap', 'AggregatedSwap', 'Arbitrage', ...
```

For autocomplete benefits without the fragility, use a const object as a reference alongside a string type:

```ts theme={null}
export const INTENT_KINDS = {
  Swap: 'Swap',
  AggregatedSwap: 'AggregatedSwap',
  Arbitrage: 'Arbitrage',
  AtomicArbitrage: 'AtomicArbitrage',
  // ... etc.
} as const;

export type IntentKind = string; // Use INTENT_KINDS constants for comparisons
```

## Staying Up to Date

* Monitor this documentation for schema change announcements.
* Pin your integration on `schema_version: 1` and alert when the value changes.
* Treat any new `intent_kind` or `motif.kind` values in production logs as signal to update your layout mappings.

<Tip>
  Because confirmed Ethereum transactions are immutable, you can cache `TxReport` responses indefinitely by tx hash. A schema version upgrade only affects **new** API calls — cached responses from the old version remain valid for their original schema.
</Tip>
