Trust intelligence

One API surface. Every domain.

Griffynx answers one question: how much should you trust this subject, and how sure can you be. Banking, payments, crypto, dating, marketplaces, investigations and compliance call the same endpoint, and differ only in what they declare about the question they are asking.

Access is by conversation · or try the free tier on yourself

43endpoints
0–100with an interval
<1stypical round trip
v1stable contract

What this is

Every call carries a subject, an intent, a purpose and a stake. You get back a score, an interval around it, and an account of the evidence that produced both. What you do with that number is yours; we do not decide for you.

Domain is never in the path. There is no /v1/lending/evaluate and there never will be. A domain is expressed in the intent, the purpose and the stake you declare, because those are the things that actually differ. The same evidence about the same subject supports a different answer for a £20 marketplace listing than for a £20,000 loan, and the difference is the stake, not the endpoint.

We return a score and an interval. We do not return a decision. An assessment says what the evidence supports and how sure it is. Turning that into approve, review or decline is policy, and policy is yours: you publish it through the control plane and we apply your label, versioned, so an audit can reconstruct which rule ran on which day. A vendor that hands you a verdict has quietly taken responsibility for your decision without taking liability for it.

Absence is a result. When a check does not answer, the response says so. When a tier you are not on would have run a check we did not, the response says that too, with the count. A thin answer that admits what it did not see is more useful than a confident one that does not.

Getting access

There is no self-serve signup, and that is deliberate. Every tenant is provisioned with the artifact types, intents and purposes it is permitted to use, and a purpose is a lawful basis rather than a dropdown. Setting that up correctly takes a conversation, and getting it wrong would put both of us somewhere neither of us wants to be.

Book a working session

Bring the decision you are trying to make and, if you can, a handful of real cases you already know the answer to. We will run them live against the production API in front of you, and you will see what it catches and what it misses on your own data rather than on a demo set we chose.

You leave with: a tenant configured for your domain, test keys, the intents and purposes your use case needs, and an honest read on whether this helps you.

hello@griffynx.com

What we will ask

  • The decision, and what it costs you to get it wrong
  • Which identifiers you already hold at that moment
  • Your lawful basis for asking
  • Volume, and how long you can wait for an answer

What we will not do

  • Issue a key without knowing what it is for
  • Promise coverage we cannot show you
  • Return a decision on your behalf

Try it free, on yourself

Griffynx Discover is the same engine at its free tier, pointed at whoever is asking. You give it one identifier you own and it shows you what the open internet already knows, with no account and no card.

What it does

Enter an email address, a phone number, a username or a domain. Discover runs the free tier of the same tool registry this API calls, then does the part a checker cannot: it looks for the connections between what it found. One handle can lead to an account, that account to a creation date, that address to a breach that also names a social profile.

You get back what was established, what refused to answer, the links it drew and how far each one can be trusted, and an honest account of the checks it did not run. The same distinction runs through it as through this API: a page that answered is a lead, and a platform that confirmed is a finding, and the two are never drawn the same way.

Why it is free

It runs on sources that cost us nothing per query, so it costs you nothing. It is also the most honest demonstration we have: rather than describing what the correlation engine does, it does it, on data you can check yourself because it is yours.

discover.griffynx.com

Authentication

A bearer token on every request. Once you have an account, you mint and revoke your own keys through the control plane. Each is shown once and stored only as a salted hash: we cannot recover a key for you, and neither can anyone who reaches our database.

# Every request
curl https://api.griffynx.com/v1/inquiries \
  -H "Authorization: Bearer gx_live_..." \
  -H "Content-Type: application/json"

Scopes are separate on purpose. A key that opens inquiries cannot mint another key, publish a policy or read the audit trail. Those need an admin key, which should not be the one deployed to your application servers.

Test keys carry the gx_test_ prefix and reach the same surface against non-production data.

Your first call

This is the whole integration for most teams. One request, one response, and the two fields that matter are the score and the interval around it.

# Request
POST /v1/inquiries
{
  "subject": {
    "presentations": [
      { "type": "EMAIL", "value": "applicant@example.com" },
      { "type": "PHONE", "value": "+919876543210" }
    ]
  },
  "intent":  "underwriting_screen",
  "purpose": "credit_assessment",
  "stake": {
    "kind": "credit",
    "amount": 250000,
    "currency": "INR",
    "reversible": false,
    "deadline_ms": 3000
  }
}
# Response
{
  "inquiry_id": "6f0a6d58-...",
  "status": "concluded",
  "assessment": {
    "score": 62,
    "low":   51,      // the interval is not decoration
    "high":  73,
    "preliminary": false,
    "methodology_version": "m1-graph",
    "label": null,   // your policy fills this, not us
    "evidence": {
      "signals": 14,
      "failed_signals": 2,
      "contradictions": 0,
      "by_trust_band": { "high": 6, "medium": 7, "low": 1 }
    }
  }
}

Read the interval, not just the score. 62 with an interval of 51–73 is a usable answer. 62 with an interval of 15–85 is the system telling you it does not know, and treating the two the same way is the most expensive mistake an integration can make. The width is a function of how much evidence answered, and the response tells you that too.

Core concepts

Five things you declare or receive. Getting these right is most of a good integration.

ConceptWhat it isWhy it exists
intent What you are about to do: onboard, underwrite, authorise, expand a case. Sets how hard the engine works and when it is allowed to stop.
purpose The lawful basis for asking. Mandatory on every call, without exception. It is written into the audit trail. When a regulator asks why you held this data, the answer is a record rather than a recollection.
stake What is at risk, how much, whether it is reversible, and how long you can wait. Fixes how narrow the interval has to be before an answer is worth acting on. A reversible listing tolerates doubt a wire transfer does not.
assessment Score, interval, methodology version, as-of, and an evidence summary. What the evidence supports. Never a decision, never a recommendation.
label Your own band applied to that score, under a policy version you published. Your risk appetite is not ours to guess. Changing a label changes an outcome; changing a score would change history.

By domain

Seven industries, one surface. Each section below is the same API called with a different declaration, which is the whole design: what differs between a lender and an investigator is the question being asked, not the evidence or the endpoint.

Why there is no /v1/banking. A vertical endpoint would mean a vertical model, and a vertical model cannot see the pattern that crosses them. The device applying for credit this morning listed on a marketplace last week; the wallet receiving funds tonight was named in a dating scam in March. One surface over one graph is what makes those the same question.

Banking and lending

Whether to open an account or extend credit to somebody whose file is thin.

What gets missed today

A bureau tells you about a person's borrowing. It cannot tell you that the email address on the application is three weeks old, that the device has applied under four other names this month, or that the phone number was issued after the employment history it claims to support. None of that is on a credit file, and all of it is knowable before you decide.

What we add

Correlation across identifiers the applicant supplied separately. A clean record on each one and a damning pattern between them is the case this exists for.

Send outcomes. Repaid, defaulted, reversed: it is the only way an assessment learns your book rather than the average book.

Payments and fintech

Whether to authorise a transfer to a payee seen for the first time, inside the authorisation window.

What gets missed today

Rules catch what they were written for. A first-time payee at an unusual hour is either a fraud or a Tuesday, and the difference is not in the transaction. It is in what the payee's identifiers have been doing elsewhere.

What we add

A preliminary answer inside your deadline, refined afterwards rather than withheld. You get something usable in the window and something better after it.

Built for India first. UPI identifiers and DLT-registered SMS headers are first-class artifact types, not a generic string field with a note attached.

Crypto and digital assets

Whether to accept a deposit from, or release funds to, a wallet address.

What gets missed today

An address is either sanctioned or it is not, and every exchange checks that. The interesting question comes before it: has this address, or the cluster around it, been named in scam reporting, drained a contract, or appeared beside identifiers you have already refused.

What we add

Sanctions screening and community scam reporting on the same call, with the address treated as an artifact that can correlate to an email, a handle or a device rather than as a string in isolation.

Ten tools on wallet addresses, four of them at no cost, including sanctions lists and scam-address reporting.

Dating and social platforms

Whether a new profile is a person, and whether it is the person it says.

What gets missed today

Romance fraud does not fail a document check, because the documents are real and belong to somebody. What gives it away is the shape of the account: a handle claimed across nine platforms in a week, photographs that predate the profile, a phone number in one country and a device in another.

What we add

The broadest coverage we have. Eighteen tools on social handles, because this is where identity is thinnest and the correlation between an account, its age and its other appearances does the most work.

The assessment is about the account, not the human being behind it. We report what public evidence supports, and we do not infer protected characteristics.

Marketplaces and platforms

Whether to let a seller list, a driver drive, or a host host.

What gets missed today

Everything on the application is true. The seller is real, the address exists, the documents check out. What you cannot see is that the identifiers reuse a network already behind three suspended accounts, because that is a fact about your own platform's history joined to public evidence.

What we add

Your suspensions are testimony. Send them as observations and they weigh on future assessments, which no external vendor can do for you, because they do not have them.

Monitors matter here. An account that was fine at onboarding and is not fine now is the common case, and asking again on a schedule is the expensive way to find out.

Investigations

What happened, who was involved, and what you can put in front of a regulator or a court.

What gets missed today

The subject is a network, not a person. Several analysts touch it, the scope grows as it goes, and at the end somebody has to show their working to somebody who was not there.

What we add

Cases carry an authorisation record, a budget, a legal hold and an append-only event log. Every expansion is one deliberate, costed hop rather than an open-ended crawl, and the export is an evidentiary bundle rather than a screenshot.

Requires an investigative tenant. Every case needs an authorisation on the record before it opens, which is a constraint we are not willing to make optional.

Compliance and AML

Whether you can show, later, that you looked and what you found.

What gets missed today

Screening tools answer the question you asked on the day you asked it. What they rarely produce is the thing an examiner actually wants: which rule ran, on which version, against which evidence, and why the answer was what it was at that moment rather than today.

What we add

Every call writes one audit row carrying the purpose you declared, and every assessment names the methodology version that produced it. Your risk bands are a policy you publish and version here, so a label from March can be reconstructed in October without anybody relying on memory.

Scores never change retroactively. A published assessment is a fact about what the evidence supported at a moment; when your appetite changes you publish a new policy and the label changes, which is a different thing and is recorded as one.

Reference

Generated from the service's own published contract, so this list cannot drift from what the API actually serves. Endpoints marked contract have a fixed, published shape and answer 501 today; they are documented because integrating against a shape that will not change is worth more than a surprise later.

Inquiries

Ask about a subject and get an assessment. This is the endpoint most integrations use and, for many, the only one they ever need.

3 endpoints · /v1/inquiries

POST /v1/inquiries live

Open Inquiry

Open an inquiry (command OpenInquiry). mode=sync waits for the first assessment within stake.deadline_ms (fast tier, target p95 under 3 s; preliminary allowed for pre_transaction). async and stream are Chunk 6b and are refused here rather than silently treated as sync, because a caller who asked for a webhook and got a body would not find out until the webhook never arrived. Rejected with I13 when purpose is missing or not allowed by policy. Every outcome, including a refusal, writes one audit row; its id comes back on the X-Griffynx-Audit-Id header so a caller can cite the call they made.

body InquiryRequest200 InquiryResponse
GET /v1/inquiries/{inquiry_id} contract

Get Inquiry

The inquiry and its latest assessment.

200 InquiryResponse
Parameters
inquiry_idpathrequired
GET /v1/inquiries/{inquiry_id}/events contract

Inquiry Events

SSE: AssessmentIssued, AssessmentRevised, InquiryConcluded. Replayable with after.

200 no body
Parameters
inquiry_idpathrequired
afterqueryoptional

Observations

Your own testimony about a subject. What you know that nobody else does enters here, carrying its provenance, and is weighed accordingly.

2 endpoints · /v1/observations

POST /v1/observations contract

Submit Observation

Submit testimony (command SubmitObservation). Enters with its provenance class; never sets a score.

body ObservationIn201 ObservationOut
POST /v1/observations/batch contract

Submit Observations

Submit many observations at once.

body ObservationIn[]201 ObservationOut[]

Outcomes

What actually happened after you decided. The single most valuable thing you can send us, and the only way an assessment gets better at your book specifically.

2 endpoints · /v1/outcomes

POST /v1/outcomes contract

Submit Outcome

Report what happened after a decision (command SubmitOutcome). Feeds calibration (E14).

body OutcomeIn201 ObservationOut
POST /v1/outcomes/batch contract

Submit Outcomes

Report many outcomes at once (a month of repayments, a day of chargebacks).

body OutcomeIn[]201 ObservationOut[]

Material

Documents, images, audio and video, declared before they are sent. Extraction produces bindings; the bytes themselves can be processed and never stored.

3 endpoints · /v1/material

POST /v1/material contract

Create Material

Declare material (command IngestMaterial). Returns a signed upload URL for the bytes, or accepts inline text. Audio and video require consent_ref. retention_mode=transient means the bytes are processed and never stored (D35). Declared C2 material is extracted to outcomes only.

body MaterialCreate201 MaterialOut
GET /v1/material/{material_id} contract

Get Material

The material's status and derivation.

200 MaterialOut
Parameters
material_idpathrequired
GET /v1/material/{material_id}/extraction contract

Get Extraction

Everything extracted from the material, each with its binding.

200 ExtractionOut
Parameters
material_idpathrequired

Cases

An investigation with more than one subject, more than one analyst, and a record of who did what. For investigative tenants; every case carries an authorisation.

14 endpoints · /v1/cases

POST /v1/cases contract

Open Case

Open a case (command OpenCase). Requires an investigative tenant (KYB) and an authorization record (I13).

body CaseCreate201 CaseOut
GET /v1/cases/{case_id} contract

Get Case

The case and its current state, derived from its event log.

200 CaseOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/assertions contract

Assert In Case

An analyst's judgement as evidence (command AssertInCase, E9).

body CaseAssertionIn201 ObservationOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/close contract

Close Case

Close the case (command CloseCase).

200 CaseOut
Parameters
case_idpathrequired
findingqueryoptional
GET /v1/cases/{case_id}/events contract

Case Events

SSE: CaseChanged, AssessmentRevised for expansions, MonitorTriggered for case monitors.

200 no body
Parameters
case_idpathrequired
afterqueryoptional
POST /v1/cases/{case_id}/expand contract

Expand Case

One hop of attribution (command ExpandCase), budgeted. With human_gate the candidates are shown first and nothing is spent until one is chosen.

body CaseExpandIn202 InquiryResponse
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/export contract

Export Case

Produce the evidentiary bundle (command ExportCase). Requires sign-off.

202 CaseExportOut
Parameters
case_idpathrequired
formatqueryoptional
GET /v1/cases/{case_id}/graph contract

Case Graph

The case graph: nodes and edges with types, weights and provenance classes.

200 CaseGraphOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/hold contract

Hold Case

Place legal hold (command HoldCase).

body CaseHoldIn200 CaseOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/intake contract

Intake Case

Bring many things into a case at once (command IntakeBatch, D43). A bounded manifest of presentations and declared material; bytes follow by hash. Each item answers for itself (accepted, duplicate, rejected); the manifest becomes one case event. Nothing is spent: gathering is expand. For open-ended intake open a session with case_id instead.

body IntakeManifest201 IntakeOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/members contract

Add Case Members

Add members (command AddCaseMembers).

body CaseMemberIn200 CaseOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/release contract

Release Case

Release legal hold (command ReleaseCase).

body CaseHoldIn200 CaseOut
Parameters
case_idpathrequired
POST /v1/cases/{case_id}/review contract

Review Case

Move the review state (command ReviewCase).

body CaseReviewIn200 CaseOut
Parameters
case_idpathrequired
GET /v1/cases/{case_id}/timeline contract

Case Timeline

Everything that happened in the case, in observed order.

200 EventEnvelope[]
Parameters
case_idpathrequired

Monitors

A standing watch on a subject. You are told when the answer changes, rather than asking again on a schedule.

4 endpoints · /v1/monitors

POST /v1/monitors contract

Open Monitor

A standing watch (command OpenMonitor).

body MonitorCreate201 MonitorOut
GET /v1/monitors/{monitor_id} contract

Get Monitor

The monitor and its last assessment.

200 MonitorOut
Parameters
monitor_idpathrequired
DELETE /v1/monitors/{monitor_id} contract

Close Monitor

End the watch (command CloseMonitor).

204 no body
Parameters
monitor_idpathrequired
GET /v1/monitors/{monitor_id}/events contract

Monitor Events

SSE: MonitorTriggered.

200 no body
Parameters
monitor_idpathrequired
afterqueryoptional

Sessions

A live connection for open-ended intake: frames in, events out, over a WebSocket.

2 endpoints · /v1/sessions

POST /v1/sessions contract

Open Session

Open a live session (command OpenSession); returns the WebSocket URL for frames and events.

body SessionOpen201 SessionOut
POST /v1/sessions/{session_id}/close contract

Close Session

Close a session (command CloseSession); the retention mode is applied.

202 no body
Parameters
session_idpathrequired
reasonqueryoptional

Entities

A subject we have resolved across more than one identifier, and its assessments in order, which is reputation over time.

2 endpoints · /v1/entities

GET /v1/entities/{entity_id} contract

Get Entity

A resolved subject as the tenant may see it.

200 EntityOut
Parameters
entity_idpathrequired
GET /v1/entities/{entity_id}/ledger contract

Get Ledger

The entity's assessments in order: reputation over time.

200 LedgerEntryOut[]
Parameters
entity_idpathrequired

Registry

What your tenant may present, ask and declare. Read it at startup rather than hard-coding a list that will drift.

3 endpoints · /v1/registry

GET /v1/registry/artifact-types contract

Artifact Types

Artifact types this tenant may present, from the loaded packs.

200 RegistryEntryOut[]
GET /v1/registry/intents contract

Intents

Intents this tenant may use.

200 RegistryEntryOut[]
GET /v1/registry/purposes contract

Purposes

Purposes this tenant's policy allows.

200 RegistryEntryOut[]

Control plane

Keys, policy, webhooks and your audit trail. Separate scope; a key that can open inquiries cannot mint another key.

6 endpoints · /v1/admin

GET /v1/admin/audit contract

Audit

The tenant's audit trail: every call and analyst action with its cost.

200 AuditEntryOut[]
Parameters
afterqueryoptional
limitqueryoptional
POST /v1/admin/keys contract

Mint Key

Mint a key (command MintKey): shown once, stored hashed (I11).

body KeyCreate201 KeyOut
GET /v1/admin/policies contract

List Policies

Every policy version, current first.

200 PolicyOut[]
POST /v1/admin/policies contract

Publish Policy

Publish a policy version (command PublishPolicy). Labels change; scores never do.

body PolicyIn201 PolicyOut
POST /v1/admin/webhooks contract

Register Webhook

Register a webhook (command RegisterWebhook).

body WebhookIn201 WebhookOut
DELETE /v1/admin/keys/{key_id} contract

Revoke Key

Revoke a key (command RevokeKey).

204 no body
Parameters
key_idpathrequired

Health

Liveness, for your monitoring. `/healthz` additionally reports the running build, the tool count and whether the service can reach its own database.

2 endpoints · /v1/health

GET /healthz live

Healthz

Liveness and the two things worth knowing before a deploy is believed. Open, like the provider service's own health endpoint: it reveals how many tools were discovered and whether the gateway's schema answers, and nothing about any tenant.

200 no body
GET /v1/health live

Health

Liveness. The only endpoint with a body today.

200 no body

Objects

The shapes you send and receive. Every one is closed: an unrecognised field is an error rather than something silently ignored.

InquiryRequest Ask about a subject at a stake, for a purpose, with an intent
subjectrequiredSubject
intentrequiredstringA registered intent id, e.g. pre_transaction, onboarding_screen.
purposerequiredstringA registered purpose id. Required on every call (I13).
stakerequiredStake
contextObservationIn[]The caller's own testimony, attached inline.
material_idsstring[]Material already ingested, to reason over.
tier_ceilingstringHighest provider tier this inquiry may use.
render"none" | "template" | "model"Whether to write the findings up as a report. none is the default because a caller that only wants the numbers should not pay for prose. A tenant may be clamped below what it asks for; the reply says which renderer ran.
render_langstringLanguage tag for the report, e.g. en, hi.
mode"sync" | "async" | "stream"
idempotency_keystring
Subject What the inquiry is about: presentations, an entity we already know, or a claim
presentationsPresentation[]
entity_idstringA subject we have resolved before.
claimClaim
Presentation One presented identifier: a registered artifact type and its value
typerequiredstringA registered artifact type id (see GET /v1/registry/artifact-types).
valuerequiredstringThe presented value; normalised by the kernel.
Stake What is at risk and how much time there is; fixes the tolerable interval and the budget
kindrequired"payment" | "credit" | "account" | "listing" | "hire" | "belief" | "other"
amountnumber
currencystring
reversiblebooleanCan the truster undo the act after the fact?
deadline_msintegerTime the caller can wait for a first answer.
InquiryResponse The inquiry resource: its state and, when concluded, its assessment
inquiry_idrequiredstring
statusrequired"accepted" | "reasoning" | "preliminary" | "concluded" | "rejected"
assessmentrequiredAssessment
findingsFindingsThe structured substrate a report is written from. Present when the inquiry concluded and the tenant's scopes allow it.
reportReportThe findings written up for a person. Present when render asked for one.
events_urlstringSSE stream of revisions while reasoning.
Assessment The public projection of a kernel Assessment
assessment_idrequiredstring
inquiry_idrequiredstring
scorerequiredinteger
lowrequiredinteger
highrequiredinteger
preliminaryrequiredbooleanTrue when the stopping rule was not yet met (pre_transaction only).
as_ofrequiredstring
methodology_versionrequiredstring
labelrequiredLabel
evidencerequiredEvidenceSummary
entity_idrequiredstring
EvidenceSummary What the tenant may see of the chain of evidence: counts and bands, never raw or provider names
signalsrequiredinteger
failed_signalsrequiredinteger
contradictionsrequiredinteger
by_provenance_classrequiredobject
by_trust_bandrequiredobject
oldest_observed_atrequiredstring
newest_observed_atrequiredstring
Findings The structured result of one inquiry, shaped to be written up
inquiry_idrequiredstring
assessment_idrequiredstring
subjectrequiredPresentation[]What was asked about, echoed back.
findingsFinding[]
absencesAbsence[]
connectionsConnection[]
coveragerequiredCoverage
generated_atrequiredstring
Finding One thing that was established about the subject
finding_idrequiredstring
aboutrequiredstringThe caller's own presented value this concerns, when it was theirs.
about_typerequiredstringThe registered artifact type of about.
kindstringWhat sort of check produced this, e.g. account_age, domain_popularity. A renderer uses it to say what a finding of this sort means; it names the question asked, never who was asked.
statementrequiredstringWhat was found, in words, with every source name removed.
provenance_classrequiredstringHow this came to be known, e.g. third_party, computed.
trust_bandrequired"high" | "medium" | "low"The banded trust of its source.
observed_atrequiredstring
data_classrequiredstringC0, C1 or C2. What handling this fact requires.
Connection An edge the engine drew between two things, and why it drew it
connection_idrequiredstringStable id for this edge, so a report can cite it.
relationrequiredstringThe registered relationship type, e.g. shares_registrant.
from_labelrequiredstringThe caller's own value where it was theirs, else its type.
from_typerequiredstring
to_labelrequiredstring
to_typerequiredstring
weightrequirednumberThe kernel's computed strength for this edge.
reasonrequiredstringWhy the edge holds, with every source name removed.
Coverage What was attempted, what answered, and what the tier put out of reach
tier_ceilingrequiredstring
checks_runrequiredinteger
checks_answeredrequiredinteger
checks_unansweredrequiredinteger
gapsCoverageGap[]
Report One inquiry, written for the person who asked
inquiry_idrequiredstring
assessment_idrequiredstring
langstring
rendered_byrequired"template" | "model"Which renderer produced this. A consumer should not otherwise be able to tell.
prompt_versionstringThe prompt that wrote it, when a model did. Null for a template.
sectionsrequiredReportSection[]
sharerequiredShareCardOut
generated_atrequiredstring
ObservationIn Testimony the caller supplies about a subject, entering with its provenance class
subjectrequiredSubject
provenance_classrequired"tenant_supplied" | "self_attested" | "analyst_asserted"
summaryrequiredstring
observed_atrequiredstring
observed_range_startstring
observed_range_endstring
purposerequiredstring
data_class"C0" | "C1" | "C2"
consent_refstringRequired for self_attested.
case_idstringRequired for analyst_asserted.
OutcomeIn What actually happened after a decision
assessment_idrequiredstring
decision_refrequiredstringThe tenant's own id for the decision they took.
kindrequired"repaid" | "defaulted" | "reversed" | "settled" | "confirmed" | "exposed" | "closed_finding" | "other"
observed_atrequiredstring
detailstring

Errors

A refusal is an answer, and it names the rule that produced it. Every call, refused or not, writes one audit row whose id comes back on X-Griffynx-Audit-Id.

StatusMeansWhat to do
200Concluded, with an assessment.Read the interval.
401No key, or a revoked one.Check the bearer token.
422Refused. The body names the rule. Do not retry unchanged. A refusal for purpose or intent means your tenant is not permitted to ask that, and asking again will be refused identically.
501A published contract with no handler yet. The shape is fixed; build against it and it will start answering.
502The engine could not complete. Retry once. The body carries the audit id for the attempt.

Versioning and status

The path carries the version. Inside /v1 we add fields and never remove them, and a shape that is published is a commitment.

What is live today. POST /v1/inquiries answers with a real assessment against real sources, and /healthz reports the running build. The remaining endpoints are published contracts: the request and response shapes are fixed and will not change under you, and each answers 501 until its handler ships.

We publish them because an institution planning an integration needs to know the shape of what is coming, and because a contract we have written down is one we can be held to.

If you have seen POST /v1/evaluate elsewhere. Some of our marketing material describes an earlier shape, with a 0–1 score and a decision string. This document is the contract; where the two disagree, this one is what the service serves.