Fidren Become a design partner
Developers

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.

Where Fidren fits

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.

  1. Evidence settlement observed on chain and outcomes the parties report Upstream
  2. Fidren Decision API recommends an action from the record, the confidence in it, and the exposure you asked for Fidren
  3. A decision an action, a ceiling, confidence, reasons and evidence Fidren
  4. Your transaction policy decides what the answer means for this payment, alongside your own controls Yours
  5. 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.

Quickstart

Zero to a decision. There is no SDK today. The core integration is one authenticated HTTP call.

Ask about a counterparty and an amount.

POST /v1/decision
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.

Authentication

One key, two accepted headers.

X-API-Key<your key>
AuthorizationBearer <your key>

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.

What the key model does not have

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.

POST /v1/decision

Three required fields, two optional.

The request.

address required
The counterparty you would be paying. Any casing.
chain required
base or polygon. See the coverage note below — they are not equally served.
amount_cents required
The requested exposure, in USD-equivalent minor units. Integer, zero or more.
currency optional
USD, USDC or USDT. Defaults to USD. Echoed back and recorded; stablecoins are read 1:1 with USD.
service_identifier optional
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.

decisionOne of the five actions.
recommended_limit_centsThe per-transaction ceiling the record supports. Returned on every decision, including BLOCK.
confidenceLOW, MEDIUM or HIGH — how much of a record the answer rests on. Never folded into the score.
trust_score0–100. Context for the action, never a substitute for it: act on decision, not on a threshold of your own over this number.
exposure_level0–4. The exposure tier this answer sits in, and where the ceiling comes from. Read it from the response — it is not a fixed function of trust_score.
reasonsPlain-language strings explaining the action.
evidenceNamed findings, each { code, detail, value? }. code is from a fixed set; value is an observation, never a weight.
evaluated_atWhen the answer was produced.
disputedThe assessed party is contesting this record, having proved control of the address. Confidence is held back; the decision is unaffected.
notificationNOTIFIED, PENDING, UNDELIVERABLE or UNREACHABLE — whether the assessed party could be told about an adverse record. UNREACHABLE is the common case.
scoring_model_versionThe model in force when this answer was produced.
decision_policy_versionThe policy in force when this answer was produced.

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.

Handling a decision

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_cents comes back and is not below the amount_cents you sent.

ALLOW_WITH_LIMIT

Treat recommended_limit_cents as the ceiling for this decision, whatever produced it. Cap the payment there, or change your request and call again — a smaller amount_cents will 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 reasons and evidence and route the transaction for review.

BLOCK

Decline the payment on these terms. Your infrastructure does the declining; Fidren blocks nothing. recommended_limit_cents still 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.

Chain coverage

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.

Errors

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 body
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "…",
    "details": [{ "field": "amount_cents", "message": "…" }]
  },
  "request_id": "…"
}

details is present only when there is something field-level to report.

400 VALIDATION_ERROR
The body failed validation. details carries a { field, message } per problem.
401 UNAUTHORIZED
No key, a malformed key, or one the service does not recognise. All three answer identically.
404 NOT_FOUND
No such resource. Not returned by the decision endpoint.
409 CONFLICT
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.
429 RATE_LIMITED
Over the per-minute allowance.
503 SERVICE_UNAVAILABLE
A dependency is unreachable. Safe to retry.
Rate limits

A per-minute allowance, reported on every response.

X-RateLimit-Limitthe allowance for this caller
X-RateLimit-Remainingwhat is left in the current window
X-RateLimit-Resetwhen the window rolls

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.

Worth knowing before you scale

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.

Request IDs

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.

There is no decision identifier

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.

Reporting outcomes

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_sign signature from the reporting address. Fetch the statement from POST /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.

Evaluating first

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.

Access

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.