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.
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.
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.
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.
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.
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.
Concept
What it is
Why 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/inquirieslive
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.
bodyInquiryRequest200InquiryResponse
GET/v1/inquiries/{inquiry_id}contract
Get Inquiry
The inquiry and its latest assessment.
200InquiryResponse
Parameters
inquiry_id
path
required
GET/v1/inquiries/{inquiry_id}/eventscontract
Inquiry Events
SSE: AssessmentIssued, AssessmentRevised, InquiryConcluded. Replayable with after.
200no body
Parameters
inquiry_id
path
required
after
query
optional
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/observationscontract
Submit Observation
Submit testimony (command SubmitObservation). Enters with its provenance class; never sets a score.
bodyObservationIn201ObservationOut
POST/v1/observations/batchcontract
Submit Observations
Submit many observations at once.
bodyObservationIn[]201ObservationOut[]
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/outcomescontract
Submit Outcome
Report what happened after a decision (command SubmitOutcome). Feeds calibration (E14).
bodyOutcomeIn201ObservationOut
POST/v1/outcomes/batchcontract
Submit Outcomes
Report many outcomes at once (a month of repayments, a day of chargebacks).
bodyOutcomeIn[]201ObservationOut[]
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/materialcontract
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.
bodyMaterialCreate201MaterialOut
GET/v1/material/{material_id}contract
Get Material
The material's status and derivation.
200MaterialOut
Parameters
material_id
path
required
GET/v1/material/{material_id}/extractioncontract
Get Extraction
Everything extracted from the material, each with its binding.
200ExtractionOut
Parameters
material_id
path
required
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/casescontract
Open Case
Open a case (command OpenCase).
Requires an investigative tenant (KYB) and an authorization record (I13).
bodyCaseCreate201CaseOut
GET/v1/cases/{case_id}contract
Get Case
The case and its current state, derived from its event log.
200CaseOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/assertionscontract
Assert In Case
An analyst's judgement as evidence (command AssertInCase, E9).
bodyCaseAssertionIn201ObservationOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/closecontract
Close Case
Close the case (command CloseCase).
200CaseOut
Parameters
case_id
path
required
finding
query
optional
GET/v1/cases/{case_id}/eventscontract
Case Events
SSE: CaseChanged, AssessmentRevised for expansions, MonitorTriggered for case monitors.
200no body
Parameters
case_id
path
required
after
query
optional
POST/v1/cases/{case_id}/expandcontract
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.
bodyCaseExpandIn202InquiryResponse
Parameters
case_id
path
required
POST/v1/cases/{case_id}/exportcontract
Export Case
Produce the evidentiary bundle (command ExportCase). Requires sign-off.
202CaseExportOut
Parameters
case_id
path
required
format
query
optional
GET/v1/cases/{case_id}/graphcontract
Case Graph
The case graph: nodes and edges with types, weights and provenance classes.
200CaseGraphOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/holdcontract
Hold Case
Place legal hold (command HoldCase).
bodyCaseHoldIn200CaseOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/intakecontract
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.
bodyIntakeManifest201IntakeOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/memberscontract
Add Case Members
Add members (command AddCaseMembers).
bodyCaseMemberIn200CaseOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/releasecontract
Release Case
Release legal hold (command ReleaseCase).
bodyCaseHoldIn200CaseOut
Parameters
case_id
path
required
POST/v1/cases/{case_id}/reviewcontract
Review Case
Move the review state (command ReviewCase).
bodyCaseReviewIn200CaseOut
Parameters
case_id
path
required
GET/v1/cases/{case_id}/timelinecontract
Case Timeline
Everything that happened in the case, in observed order.
200EventEnvelope[]
Parameters
case_id
path
required
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/monitorscontract
Open Monitor
A standing watch (command OpenMonitor).
bodyMonitorCreate201MonitorOut
GET/v1/monitors/{monitor_id}contract
Get Monitor
The monitor and its last assessment.
200MonitorOut
Parameters
monitor_id
path
required
DELETE/v1/monitors/{monitor_id}contract
Close Monitor
End the watch (command CloseMonitor).
204no body
Parameters
monitor_id
path
required
GET/v1/monitors/{monitor_id}/eventscontract
Monitor Events
SSE: MonitorTriggered.
200no body
Parameters
monitor_id
path
required
after
query
optional
Sessions
A live connection for open-ended intake: frames in, events out, over a WebSocket.
2 endpoints ·
/v1/sessions
POST/v1/sessionscontract
Open Session
Open a live session (command OpenSession); returns the WebSocket URL for frames and events.
bodySessionOpen201SessionOut
POST/v1/sessions/{session_id}/closecontract
Close Session
Close a session (command CloseSession); the retention mode is applied.
202no body
Parameters
session_id
path
required
reason
query
optional
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.
200EntityOut
Parameters
entity_id
path
required
GET/v1/entities/{entity_id}/ledgercontract
Get Ledger
The entity's assessments in order: reputation over time.
200LedgerEntryOut[]
Parameters
entity_id
path
required
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-typescontract
Artifact Types
Artifact types this tenant may present, from the loaded packs.
200RegistryEntryOut[]
GET/v1/registry/intentscontract
Intents
Intents this tenant may use.
200RegistryEntryOut[]
GET/v1/registry/purposescontract
Purposes
Purposes this tenant's policy allows.
200RegistryEntryOut[]
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/auditcontract
Audit
The tenant's audit trail: every call and analyst action with its cost.
200AuditEntryOut[]
Parameters
after
query
optional
limit
query
optional
POST/v1/admin/keyscontract
Mint Key
Mint a key (command MintKey): shown once, stored hashed (I11).
bodyKeyCreate201KeyOut
GET/v1/admin/policiescontract
List Policies
Every policy version, current first.
200PolicyOut[]
POST/v1/admin/policiescontract
Publish Policy
Publish a policy version (command PublishPolicy). Labels change; scores never do.
bodyPolicyIn201PolicyOut
POST/v1/admin/webhookscontract
Register Webhook
Register a webhook (command RegisterWebhook).
bodyWebhookIn201WebhookOut
DELETE/v1/admin/keys/{key_id}contract
Revoke Key
Revoke a key (command RevokeKey).
204no body
Parameters
key_id
path
required
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/healthzlive
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.
200no body
GET/v1/healthlive
Health
Liveness. The only endpoint with a body today.
200no body
Objects
The shapes you send and receive. Every one is closed: an unrecognised field is an
error rather than something silently ignored.
InquiryRequestAsk about a subject at a stake, for a purpose, with an intent
subjectrequired
Subject
intentrequired
string
A registered intent id, e.g. pre_transaction, onboarding_screen.
purposerequired
string
A registered purpose id. Required on every call (I13).
stakerequired
Stake
context
ObservationIn[]
The caller's own testimony, attached inline.
material_ids
string[]
Material already ingested, to reason over.
tier_ceiling
string
Highest 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_lang
string
Language tag for the report, e.g. en, hi.
mode
"sync" | "async" | "stream"
idempotency_key
string
SubjectWhat the inquiry is about: presentations, an entity we already know, or a claim
presentations
Presentation[]
entity_id
string
A subject we have resolved before.
claim
Claim
PresentationOne presented identifier: a registered artifact type and its value
typerequired
string
A registered artifact type id (see GET /v1/registry/artifact-types).
valuerequired
string
The presented value; normalised by the kernel.
StakeWhat is at risk and how much time there is; fixes the tolerable interval and the budget
The structured substrate a report is written from. Present when the inquiry concluded and the tenant's scopes allow it.
report
Report
The findings written up for a person. Present when render asked for one.
events_url
string
SSE stream of revisions while reasoning.
AssessmentThe public projection of a kernel Assessment
assessment_idrequired
string
inquiry_idrequired
string
scorerequired
integer
lowrequired
integer
highrequired
integer
preliminaryrequired
boolean
True when the stopping rule was not yet met (pre_transaction only).
as_ofrequired
string
methodology_versionrequired
string
labelrequired
Label
evidencerequired
EvidenceSummary
entity_idrequired
string
EvidenceSummaryWhat the tenant may see of the chain of evidence: counts and bands, never raw or provider names
signalsrequired
integer
failed_signalsrequired
integer
contradictionsrequired
integer
by_provenance_classrequired
object
by_trust_bandrequired
object
oldest_observed_atrequired
string
newest_observed_atrequired
string
FindingsThe structured result of one inquiry, shaped to be written up
inquiry_idrequired
string
assessment_idrequired
string
subjectrequired
Presentation[]
What was asked about, echoed back.
findings
Finding[]
absences
Absence[]
connections
Connection[]
coveragerequired
Coverage
generated_atrequired
string
FindingOne thing that was established about the subject
finding_idrequired
string
aboutrequired
string
The caller's own presented value this concerns, when it was theirs.
about_typerequired
string
The registered artifact type of about.
kind
string
What 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.
statementrequired
string
What was found, in words, with every source name removed.
provenance_classrequired
string
How this came to be known, e.g. third_party, computed.
trust_bandrequired
"high" | "medium" | "low"
The banded trust of its source.
observed_atrequired
string
data_classrequired
string
C0, C1 or C2. What handling this fact requires.
ConnectionAn edge the engine drew between two things, and why it drew it
connection_idrequired
string
Stable id for this edge, so a report can cite it.
relationrequired
string
The registered relationship type, e.g. shares_registrant.
from_labelrequired
string
The caller's own value where it was theirs, else its type.
from_typerequired
string
to_labelrequired
string
to_typerequired
string
weightrequired
number
The kernel's computed strength for this edge.
reasonrequired
string
Why the edge holds, with every source name removed.
CoverageWhat was attempted, what answered, and what the tier put out of reach
tier_ceilingrequired
string
checks_runrequired
integer
checks_answeredrequired
integer
checks_unansweredrequired
integer
gaps
CoverageGap[]
ReportOne inquiry, written for the person who asked
inquiry_idrequired
string
assessment_idrequired
string
lang
string
rendered_byrequired
"template" | "model"
Which renderer produced this. A consumer should not otherwise be able to tell.
prompt_version
string
The prompt that wrote it, when a model did. Null for a template.
sectionsrequired
ReportSection[]
sharerequired
ShareCardOut
generated_atrequired
string
ObservationInTestimony the caller supplies about a subject, entering with its provenance class
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.
Status
Means
What to do
200
Concluded, with an assessment.
Read the interval.
401
No key, or a revoked one.
Check the bearer token.
422
Refused. 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.
501
A published contract with no handler yet.
The shape is fixed; build against it and it will start answering.
502
The 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.