One authenticated call, before you pay.
Fidren answers whether a counterparty should be paid, up to how much, and under what conditions. You call it before the payment; what happens next is yours.
This page documents the API as it exists today. Where something is not built, it says so rather than describing it in the present tense.
A decision layer, between evidence and execution. Not a replacement for either.
One layer of five.
Fidren does not ingest arbitrary third-party intelligence into the record today, and does not move your money. It turns a record into a recommended action, which is the step between the two that nothing else in a payment stack owns.
- Evidence settlement observed on chain and outcomes the parties report Upstream
- Fidren Decision API recommends an action from the record, the confidence in it, and the exposure you asked for Fidren
- A decision an action, a ceiling, confidence, reasons and evidence Fidren
- Your transaction policy decides what the answer means for this payment, alongside your own controls Yours
- Your wallet and payment rails enforce and execute. Fidren is not on this path Yours
Screening and blockchain-intelligence tools answer a different question and sit beside Fidren rather than inside it: there is no path today by which a third-party signal enters the record Fidren answers from. Run both, and combine them in your own transaction policy. Wallet and transaction-governance infrastructure sits downstream and does the enforcing. Fidren complements both; it is not a wallet, a custody provider, a payment processor or an execution engine.
Zero to a decision. There is no SDK today. The core integration is one authenticated HTTP call.
Ask about a counterparty and an amount.
curl -X POST https://api.fidren.net/v1/decision \
-H "X-API-Key: <your key>" \
-H "Content-Type: application/json" \
-d '{
"address": "0x8581784d3e598cca3482375cff2409ac9dd8c402",
"chain": "base",
"amount_cents": 1000,
"currency": "USD"
}'
The answer comes back on the same call. Read
decision and act on it; read
recommended_limit_cents to know the ceiling
the record supports. Nothing else is required to integrate.
Access is provisioned per partner while Fidren is early, so the first step is a conversation rather than a signup.
One key, two accepted headers.
Both are accepted because agent frameworks differ in which
headers they can set. Keys are 32 random bytes, base64url-encoded,
prefixed fdrn_. The plaintext is generated
server-side and shown once at creation; the database stores only a
SHA-256 digest, so a leaked database yields no usable credential. A
missing, malformed or unrecognised key all return the same
401 with the same message, so error text
cannot be used to enumerate valid keys.
No rotation workflow — revoke and create. No expiry. No scopes and no per-key permissions. No IP restrictions. No separate test and live keys, and no sandbox: the key you are issued talks to the real service. No self-service creation. Plan your integration around a single long-lived credential you keep out of source control.
Three required fields, two optional.
The request.
addressrequired- The counterparty you would be paying. Any casing.
chainrequired- base or polygon. See the coverage note below — they are not equally served.
amount_centsrequired- The requested exposure, in USD-equivalent minor units. Integer, zero or more.
currencyoptional- USD, USDC or USDT. Defaults to USD. Echoed back and recorded; stablecoins are read 1:1 with USD.
service_identifieroptional- A caller-side label for the service being paid. Yours, not interpreted.
The response.
Every field below is present on every successful call.
currency comes back too, echoing what you
sent.
decision, not on a threshold of your own over this number.code is from a fixed set; value is an observation, never a weight.The per-dimension scoring breakdown is not in the response and is not published anywhere. Naming which lever moves a score would turn a risk signal into a checklist for gaming it.
Fidren returns the action. You enforce it — there is no path by which Fidren does.
What to do with each answer.
- ALLOW
Proceed with the payment you intended.
recommended_limit_centscomes back and is not below theamount_centsyou sent.- ALLOW_WITH_LIMIT
Treat
recommended_limit_centsas the ceiling for this decision, whatever produced it. Cap the payment there, or change your request and call again — a smalleramount_centswill not necessarily change the action.- ALLOW_WITH_ESCROW
Route settlement through an escrow you choose and control, still within
recommended_limit_cents. Fidren recommends the condition; it does not provide, operate or execute the escrow.- REVIEW
Do not treat REVIEW as a transient API error or put it in an automatic retry loop. Read
reasonsandevidenceand route the transaction for review.- BLOCK
Decline the payment on these terms. Your infrastructure does the declining; Fidren blocks nothing.
recommended_limit_centsstill comes back and is not permission.
This is handling. What the five actions mean, and how confidence differs from risk, is on Product. Treat a Fidren answer as one input to your transaction policy rather than as the only control.
The one place the contract is wider than the service.
Base is indexed. Polygon is not.
chain validates against
base and
polygon, but only Base is observed today —
nothing indexes Polygon. A Polygon request is accepted and answered
from an empty record, which will read as an unknown counterparty
whatever that address has actually done. That is a materially
different thing from support, so plan for Base.
Fidren is not chain-agnostic and this page will not describe it that way while one chain is served. When another lands, it will be named here.
One shape, whatever went wrong.
Every failure returns the same envelope.
The statuses below are the ones the contract documents. An
unhandled fault returns the same shape with a
500, which the contract does not yet
declare per route.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "…",
"details": [{ "field": "amount_cents", "message": "…" }]
},
"request_id": "…"
}
details is present only when there is
something field-level to report.
400VALIDATION_ERROR- The body failed validation.
detailscarries a { field, message } per problem. 401UNAUTHORIZED- No key, a malformed key, or one the service does not recognise. All three answer identically.
404NOT_FOUND- No such resource. Not returned by the decision endpoint.
409CONFLICT- The report cannot be appended as submitted: an invalid lifecycle transition, a side already reported by a different address, or a chain that moved during the write. Only the last is worth retrying.
429RATE_LIMITED- Over the per-minute allowance.
503SERVICE_UNAVAILABLE- A dependency is unreachable. Safe to retry.
A per-minute allowance, reported on every response.
The bucket is chosen from a credential Fidren issued, never from the one in the request: a key the service does not recognise buys nothing and falls back to an allowance keyed on your network address. Authenticated callers draw a larger per-minute allowance than anonymous ones. Read the headers rather than hard-coding a number — the allowance is a deployment setting, not a published plan and not a per-key negotiation.
The counter is held in memory, per process. A deployment running more than one API instance would hold a separate budget in each, so the effective allowance is the sum rather than the configured number. There are no quotas, no plans and no usage-based tiers — rate limiting is not billing.
The distinction that causes integration bugs.
A request ID is not a decision ID.
Every response carries
x-request-id, and every error body repeats
it as request_id. Supply your own on the
request header and it is honoured when it matches a conservative
pattern; anything else is replaced with a generated value rather
than sanitised, because a header is caller-controlled and log files
are read by tools that interpret what they find.
A request ID identifies one HTTP call, for support and correlation. It is not a durable handle for retrieving a past decision, and no such handle exists — the API returns no decision ID and there is no endpoint that reads a decision back. If you need the answer later, store it when you receive it.
Not required to integrate. It is what makes the next answer better.
Telling Fidren how it went.
After an operation concludes, either side may report the outcome
to POST /v1/receipts. Each side keeps its
own hash chain and the server computes the links, so a reporter
cannot reorder or edit its own account afterwards. Three levels are
worth keeping apart:
- Recorded
- Name a side and an address in the request body. It is stored, attributed to your API key — no other endpoint or parameter is involved.
- Signed
- Optionally, the report carries a
personal_signsignature from the reporting address. Fetch the statement fromPOST /v1/receipts/signing-message, sign it, resubmit. A signature is verified and stored only if it verifies. Only a signature shows the reporter controls the address it names. - Corroborated
- Automatic once both sides have separately called this endpoint and their signed accounts agree — nothing further to call.
A reported outcome is never treated as verified truth — the chain establishes integrity and ordering against the reporter, not that the account is accurate. Separately signed reports can still come from parties under common control. Why that limit exists, and what it does and does not prove, is on Security.
You can call it without acting on it.
A practical first step is to call Fidren alongside your existing flow, log the answers and compare them, without gating any payment on them. Nothing is switched on at Fidren's end to do that — there is no mode, no flag and no parameter, because Fidren never had the ability to act in the first place. What changes is only whether your code honours the answer.
Shadow Mode describes the posture. Security boundaries, the non-custodial architecture and what is redacted from logs are on Security.
Keys are provisioned per partner. Commercial pricing is not published yet.
Bring a system that is about to pay someone.
The integration conversation is a short one when there is a real flow to point at. If you have one, we would like to hear about it.