I’m registered but receive no requests
Every cause is on the eligibility path, which runs before your endpoint is ever called:- Chain mismatch: you declared
chainIdsthat exclude the requests being made. Omitting the field entirely means “every chain”. - Debt token mismatch:
supportedTokensfilters on the request’s debt token only. A solver scoped to collateral assets it likes will silently match nothing. - Venue mismatch:
supportedVenuesfilters on the request’svenueBitmap. A solver scoped to one venue receives nothing from borrowers who allowed only the other. - Borrower blocked: a per-endpoint compliance blocklist excludes that borrower for your endpoint.
- Registry not refreshed yet: changes normally propagate within 5 minutes, and longer when a refresh fails.
I changed my registry entry and nothing happened
The coordinator caches the registry and refreshes it on a 5-minute interval. A new endpoint, a changed timeout, or widened token scope will not apply immediately. A refresh that fails is not retried until the next interval: the coordinator keeps serving the cached registry rather than failing quote rounds, so a change occasionally takes more than one interval to land. Wait out the interval before investigating further.My quotes are being dropped and I get no error
Validation failures are never returned to your endpoint: the quote is dropped and the round proceeds. Work through Validation in order; the most common causes are a signature over terms that diverged from the response, adeadline outside the two-minute window, and venueId sent as a bitmask instead of an index.
I’m getting 404 No quotes available
The coordinator returns 404 to the caller when no valid quote survived the round, so when you test your endpoint end to end, this one symptom covers every failure mode. Check in this order:
- You were never called: an eligibility filter excluded you; see I’m registered but receive no requests.
- You declined: HTTP
404orbond: "0"from your endpoint is a non-quote by design. - You timed out: the response budget is measured to your last byte, network transit included; see How long do I have to respond?
- Your quote was dropped in validation: drops are silent; work through Validation in order.
What does the signature actually cover?
The on-chainQuote struct, which mixes fields from the borrower’s request with fields from your quote. If you rebuild the request side from anything other than the request you were handed, recovery will produce a different address and the quote is dropped. Fields are listed in Get Started.
When are two signatures required?
Only when you fund your bond per quote. TheQuote signature is always required and binds you to the terms. The Permit2 signature exists because Iris.take() pulls your bond and you are not in the call path at that moment to approve it, so the authorisation travels with the quote. A solver maintaining a standing ERC-20 allowance to Iris needs no per-quote authorisation and omits permit2Nonce and permit2Signature together.
Should I keep a standing approval or sign a permit per quote?
Both fund the bond; the trade is between operational convenience and authorisation scope, and the choice is yours.- Standing approval: one ERC-20 approval to
Irisper debt token, consumed take after take. Nothing extra to sign per quote, and no nonce to collide between concurrent quotes in the same debt token. The allowance is open-ended and sits on your solver account until you revoke it. - Per-quote permit: authorisation that is bond-exact and dies with the quote, so nothing open-ended rests on your account. Permit2 nonces are sequential, though: quotes live in the same window share one, and if two are both taken the second reverts at
Iris.take(), which effectively limits you to one live quote per debt token per TTL window. The Permit2 section documents the failure mode.
Iris.take() because the first take consumed the balance. Whichever authorisation you choose, keep the sum of your live quotes’ bonds within what you hold.
Can I reuse a Permit2 signature?
No. It authorises exactly one quote’s bond amount, and Permit2 allowance nonces are sequential, so it is single-use by construction. If you quote concurrently in the same debt token, keep a standing ERC-20 approval toIris and omit the pair entirely; a permitless quote has no nonce to contend.
Can I use a smart contract wallet?
Not yet. Signature verification is EOA-only: ERC-1271 signatures cannot currently be verified and will be rejected. Signatures must be 65-byter || s || v; 64-byte EIP-2098 compact signatures are deliberately rejected because they cannot be recovered.
How long do I have to respond?
5 seconds by default, measured to your last byte, network transit included. A higher budget can be configured per solver during onboarding. Exceeding it abandons your quote for that round. The coordinator runs in AWSus-east-2. If you are chasing latency, co-locating your endpoint near that region returns the round-trip time to your pricing budget: ensure your infrastructure can consistently answer well inside its window.
Is it better to decline or to stay silent?
Decline explicitly: HTTP404 or bond: "0". Both are recorded as non-quotes rather than failures. Timing out or returning a malformed body counts against your endpoint’s health, while declining does not.
How is the winner chosen?
LowestfixedRate among quotes that survive validation. Nothing else is scored: not bond size, not latency, not response order. Being ranked best does not guarantee settlement, though: the borrower receives every valid quote in allQuotes and may take a different one, for example from a solver they already trust.
Do I find out whether I won?
Not from the coordinator; it returns the result to the borrower, not to solvers. A quote is settled when the borrower callsIris.take(), so on-chain activity against your solver address is the signal. Loans you have underwritten are queryable by solver address; see Solver Book.
My quote won but take() reverted
Expected in some cases. Coordinator validation is convenience-grade: it drops definitively-unsubmittable quotes but skips checks it cannot run, and the contract is the real authority. The usual causes are an expired deadline, an insufficient bond that skipped validation, your bond allowance no longer being available at settlement, the balance behind your bond having been consumed by an earlier take of another quote, or a Permit2 nonce collision: another quote you signed in the same window was taken first and consumed the shared nonce.

