Writing

Eight ways to say no

29 September 2026 · figures measured 29 September 2026

Ask eight swap providers to price the same transfer and seven of them answer. Ask them to price one that is too small and seven of them refuse — and no two refuse in the same way.

That sounds like a detail for whoever writes the integration. It is, but it is also the reason a swap site can tell you the wrong thing about your own transfer.

The same request, twice

Bitcoin into Tether on Tron, every provider asked in one pass. The only difference between the two rows is the amount:

SendingQuoted itRefused it
0.05 BTC — about $4,1007 of 81 of 8
0.00002 BTC — about $1.701 of 87 of 8

The one refusal in the first row is the same one in both: an authorisation error that has nothing to do with the amount. The other six only appear when the transfer is too small.

Seven refusals, seven shapes

Here is what each one actually said, measured on 29 September 2026, in the same pass, about the same pair:

ProviderStatusWhat it said
GhostSwap400Amount is below the minimum for btc → usdtrx. Minimum: 0.00036093 btc.
Changelly-32602Invalid amount for pair btc->usdtrx. Minimal amount is 0.00036093 btc
ChangeNOW400Out of min amount
SimpleSwap422Amount does not fall within the range. Min: 0.00015927, max: null
StealthEX400InvalidAmount: Amount is out of range
LetsExchange—amount below the pair's floor. Minimum: 0.001
FixedFloat401Not have permission

Two of them name the floor. Two name the pair. One returns a JSON-RPC error code rather than an HTTP status. One uses 422 where the others use 400. One says nothing about amounts at all, because its problem is a key rather than a number — and it says exactly the same thing when the transfer is a perfectly ordinary size.

Why it matters to you and not just to a developer

A router asking all eight at once has to sort these into categories before it can tell you anything: too small, wrong coin, wrong chain, not authorised, provider down. Nothing in the responses makes that easy. There is no shared status, no shared field, no shared vocabulary — only prose, written by eight different teams who never agreed on anything.

Sort them wrong and the error you see is wrong. A transfer below one provider's minimum gets reported as an unsupported coin. An expired key gets reported as an outage. A chain spelled the way one API expects and another does not gets reported as a coin that does not exist — which is a separate piece of the same problem, and the one that kept Monero off this site for a fortnight.

One coincidence worth not believing

GhostSwap and Changelly report the same minimum to eight decimal places in the table above — 0.00036093 — while the others are an order of magnitude apart. That looks like two brands over one pool, and it is tempting to say so.

Measured across six pairs on two days, it does not hold. The two agree exactly on some pairs and differ by about 0.003% on others, and which is which changes between one reading and the next. Their prices differ too. That is the signature of two services computing limits from nearly the same reference price at slightly different moments, not of one service wearing two names. The interesting version of this claim did not survive being measured twice, which is the only reason it is not in this post as a finding.

What this does not tell you

Nothing here says which provider is better. A terse error is not a worse service — several of the tersest have the best rates, and the one with the most helpful message is not the cheapest. It says only that the eight do not answer alike, and that anything presenting them as one catalogue is doing translation work you cannot see.

The minimums are a reading rather than a constant. They are recalculated continuously: the same pair measured twice within an hour returned floors differing in the fourth decimal. The shapes of the refusals are what stays the same.

Method

Every provider was asked for the same pair at the same two amounts in a single pass, so the answers are comparable to one another. The wording is quoted verbatim from each provider's response, trimmed only where a message repeated the full request URL. The FixedFloat row is an authorisation failure on this deployment rather than a judgement about that provider; it returns the same response to an unauthenticated request, to an invalid key and to a real one, which is why it cannot be told apart from the outside.

The same figures, refreshed every fifteen minutes rather than frozen on the day this was written, are on the providers page.

Plan an exchange

Every figure above can be checked against the providers yourself — no account, no sign-up, and nothing is held for you at any point.