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

# Best Practices

> The operating rules that keep your RFQ integration on the full liquidity surface.

Consider this the RFQ API's field handbook. None of these rules is theoretical - each one exists because some integrator broke it and watched an LP respond.

Every desk quoting on TetraFi runs its own risk engine and profiles the flow it receives, source by source. Adversarial-looking patterns get priced against, then filtered out. Hold to the six rules below and the whole liquidity surface stays open to you; drift from them and the degradation is gradual, then total.

## 1. Filter before you quote

Let the [price feed](/price-api/quickstart) do your screening. `/rfq/quotes` should fire only after the stream has already told you the trade clears your bar.

The stream costs LPs nothing and refreshes continuously; a firm quote is a commitment a desk must stand behind, which is exactly why it's metered per key.

```python theme={null} theme={null}
# Wasteful: a firm quote per candidate intent
quotes = httpx.post(QUOTES_URL, json=...)  # spends metered quota on maybe-trades

# Better: let streamed depth gate the call
if stream_depth_for(corridor) >= intent_size:
    quotes = httpx.post(QUOTES_URL, json=...)
```

See [Estimating VWAP](/price-api/guides/vwap-estimation) for the canonical pattern.

## 2. Execute what you quote

A quote captures the market at a single instant. Sitting on it, letting the market move, and firing only once the frozen price has drifted into your favour is **adverse selection by design** - and desks see it immediately.

**Do it this way:** the streamed prices power every upstream decision; the firm quote is requested at the instant of execution, never before.

## 3. One intent, one quote

Slicing - splitting a single fill intent into several smaller quote requests - comes in two flavours, and LPs detect both:

* **Fragmenting one fill:** asking four times for `2M USDC → WETH` when the real intent is a single `8M` fill.
* **Doubling one execution:** pulling two `20M USDC → WETH` quotes at once and executing both, whether bundled or in back-to-back blocks. Both were priced against the same full inventory; only one can survive its draw-down. A few seconds between blocks replenishes nothing - the moment both quotes were requested together, it was slicing.

When the final size is genuinely uncertain, [partial fills](/rfq-api/guides/partial-fills) exist for exactly that: quote `8M` with `partialFill: true` and settle at `6.5M` on unchanged terms - a supported pattern, not a hostile one.

Partial fills also solve the AMM top-up case: when part of a trade routes through an AMM, its true output isn't known until execution. Quote the maximum you might need, let the order partially fill down to what the AMM leg actually produced, and skip a second round trip on the critical path.

```python theme={null} theme={null}
# Hostile: fragmenting one intent into four requests
for _ in range(4):
    httpx.post(QUOTES_URL, json=intent_for("2000000"))

# Supported: a single quote with room to settle smaller
httpx.post(QUOTES_URL, json=intent_for("8000000", partial_fill=True))
# Any size up to the quoted amount settles on the same terms.
```

## 4. Quote only what's tradable

Firing quotes at corridors nobody serves wastes desk compute and tells everyone your pipeline has no filter. Gate on the pair list instead:

```python theme={null} theme={null}
import httpx

pairs = httpx.get(
    "https://api.tetrafi.io/api/v1/pairs",
    headers={"X-API-Key": KEY},
).json()["pairs"]

tradable = {(p["input"]["chainId"], p["input"]["address"].lower(),
             p["output"]["chainId"], p["output"]["address"].lower()) for p in pairs}

if (10, usdc_op.lower(), 8453, usdc_base.lower()) in tradable:
    quotes = httpx.post(QUOTES_URL, json=..., headers=...)
```

The pair list is the definitive answer to "can this be quoted?" - anything on it combines with any other supported leg.

## 5. Firm means firm

An RFQ quote is **executable at its stated terms until `validUntil`**, enforced by the escrow. When your router compares a TetraFi quote against AMM routes, don't haircut it with the "expected slippage" you'd apply to a pool price:

| Source              | Returned price        | What you actually receive            |
| ------------------- | --------------------- | ------------------------------------ |
| TetraFi RFQ         | Firm, escrow-enforced | The quoted terms - or a refund       |
| AMM (Uniswap, etc.) | Mid-price estimate    | Estimate minus slippage and MEV cost |

Treat those two numbers as the same kind of thing and your router will systematically send flow away from its genuinely best price.

## 6. Show us whose flow it is

Attribution fields tell TetraFi and the LPs who is really behind a request. They feed abuse prevention and per-source reputation, so accuracy directly shapes the pricing you receive:

| Field                 | Send when                                          | Value                                                        |
| --------------------- | -------------------------------------------------- | ------------------------------------------------------------ |
| `user`                | Always (required)                                  | The wallet that signs and funds the order                    |
| `directUserId`        | You're a broker acting for onboarded end-users     | The end-user's ID from your workspace's direct-user registry |
| `signerWallet`        | The signing wallet differs from the funding `user` | The wallet that will actually sign                           |
| `metadata` source tag | You aggregate flow from multiple upstream sources  | A stable identifier per sub-source                           |

**Direct integrator** - `user` is the end-user's own wallet, nothing in between: the required field is all you need.

**Broker flows** - your users onboard through your workspace; send `directUserId` so screening and reputation attach to the actual person, not your whole integration.

**Aggregated flows** - tag each upstream source consistently in `metadata`. Reputation then accrues per sub-source, so one bad downstream partner can't taint the rest of your flow.

<Warning>
  **Truthful attribution is self-interest.** Misattributed flow degrades both screening and reputation in one stroke, and the pricing consequences land on your whole integration - persistently wrong data ends in de-prioritisation.
</Warning>

## Pre-launch checklist

Before going live, confirm:

* Streamed prices, not firm quotes, do the pre-trade screening
* Quotes go straight from issuance to execution, never through a cache
* Each intended fill maps to exactly one quote, with `partialFill` absorbing size uncertainty
* No fill ever executes more than one quote
* `/api/v1/pairs` vouches for every pair you quote
* Pool estimates get their slippage haircut; firm quotes don't
* Attribution fields name the flow's true origin

Hold all seven and your access compounds in your favour; let them slip and the decay is silent until it isn't.
