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

# Intents and RFQs

> Discover intent datasets, choose the right Polaris client method, and reconstruct RFQ and intent lifecycles.

Use this guide when you want to analyze requests for quote, solver responses,
executable intents, and settlement observations. Polaris standardizes these
records under `market="intents"` while retaining source-specific fields.

## Representative coverage

This snapshot comes from the public Catalog at
`2026-08-27T20:33:06.675Z`. Use [Catalog](/reference/catalog) to confirm the
current sources, bounds, and access state before querying.

| Source ID  | Market    | Access  |
| ---------- | --------- | ------- |
| `lifi`     | `intents` | Preview |
| `uniswapx` | `intents` | Preview |

## Choose a client method

| Task                           | Python         | TypeScript     | Rust                       |
| ------------------------------ | -------------- | -------------- | -------------------------- |
| Discover sources and bounds    | `catalog(...)` | `catalog(...)` | `catalog(CatalogQuery)`    |
| Read typed intent observations | `intents(...)` | `intents(...)` | `intents(HistoricalQuery)` |
| Subscribe to current updates   | `stream(...)`  | `stream(...)`  | `stream(StreamQuery)`      |
| Read mixed standardized events | `events(...)`  | `events(...)`  | `events(HistoricalQuery)`  |
| Replay stored events           | `replay(...)`  | `replay(...)`  | `replay(ReplayQuery)`      |
| Inspect venue-native payloads  | `raw(...)`     | Not exposed    | `raw(RawQuery)`            |

Use `intents` when you only need canonical `IntentEvent` observations. Use
`events` or `replay` when intent records must remain interleaved with other
standardized events. Use `raw` when an analysis depends on fields outside the
canonical intent model.

See [Python SDK](/sdks/python), [TypeScript SDK](/sdks/typescript), and
[Rust SDK](/sdks/rust) for complete signatures and return behavior.

## Reconstruct lifecycle summaries

Each returned row is an observation, not a complete lifecycle snapshot. Keep
the stored order, retain partial rows, and select the latest non-null value when
you derive a summary.

The following example uses Catalog to choose a bounded six-hour window, builds
an observation timeline, and reports the latest known state for each captured
identifier.

```python theme={null}
from datetime import timedelta

import pandas as pd
from polaris_data import PolarisClient

source = "uniswapx"
market = "intents"

with PolarisClient() as client:
    catalog = client.catalog(source=source, market=market)
    coverage = catalog["markets"][0]
    coverage_start = pd.Timestamp(coverage["start"])
    coverage_end = pd.Timestamp(coverage["end"])
    public_cutoff = coverage["access"].get("public_cutoff_date")
    if public_cutoff:
        public_day = pd.Timestamp(public_cutoff, tz="UTC")
        start = max(coverage_start, public_day)
        end = min(coverage_end, start + timedelta(hours=6))
    else:
        end = coverage_end
        start = max(coverage_start, end - timedelta(hours=6))

    observations = list(
        client.intents(
            source=source,
            market=market,
            from_=start.to_pydatetime(),
            to=end.to_pydatetime(),
            allow_gaps=True,
        )
    )

timeline_rows = []
for observation in observations:
    data = observation.get("data", {})
    intent_id = data.get("intent_id")
    rfq_id = data.get("rfq_id")
    correlation_id = (
        f"intent:{intent_id}" if intent_id else f"rfq:{rfq_id}" if rfq_id else None
    )
    if correlation_id is None:
        continue

    timeline_rows.append(
        {
            "timestamp": observation.get(
                "collector_timestamp", observation.get("timestamp")
            ),
            "sequence": observation.get("collector_sequence", 0),
            "correlation_id": correlation_id,
            "intent_id": intent_id,
            "rfq_id": rfq_id,
            "status": data.get("status"),
            "quote_id": (data.get("quote") or {}).get("quote_id"),
            "transaction_count": len(data.get("transactions") or []),
            "settled_at": data.get("settled_at"),
        }
    )

if not timeline_rows:
    print("No identifiable intent or RFQ observations in the selected interval.")
else:
    timeline = pd.DataFrame.from_records(timeline_rows).sort_values(
        ["timestamp", "sequence"]
    )

    def latest_non_null(values):
        values = values.dropna()
        return values.iloc[-1] if not values.empty else None

    summary = (
        timeline.groupby("correlation_id", sort=False)
        .agg(
            first_seen=("timestamp", "min"),
            last_seen=("timestamp", "max"),
            observations=("timestamp", "size"),
            latest_status=("status", latest_non_null),
            latest_quote_id=("quote_id", latest_non_null),
            transaction_count=("transaction_count", "max"),
            settled_at=("settled_at", latest_non_null),
        )
        .reset_index()
    )
    summary["has_settlement"] = (
        summary["settled_at"].notna() | summary["transaction_count"].gt(0)
    )
    print(summary.sort_values("last_seen", ascending=False).head(20))
```

This keeps status-only and settlement-only rows instead of treating their empty
arrays as deletion instructions. Retain `timeline` when you need the complete
sequence behind a summary.

<Warning>
  Do not infer that an RFQ and an executable intent belong to the same lifecycle
  only because their assets, amounts, or timestamps look similar. Correlate them
  only when a captured row or venue identifier establishes the relationship.
</Warning>

## Related documentation

* [Intents and RFQs schema](/schemas/intents-and-rfqs) for canonical fields, statuses, and multi-language examples
* [Event envelope](/concepts/event-envelope) for stored ordering and timestamp semantics
* [Catalog](/reference/catalog) for current source and access metadata
* [Events](/schemas/events) for mixed standardized event streams
