GET /v2/methodologies/:lenderId/active and GET /v2/methodologies/:lenderId/:methodologyHash resolve the per-lender underwriting methodology document linked from a Schema B attestation. Used by regulators and third-party verifiers to independently audit a lender’s underwriting basis.
These endpoints are public — no JWT, no IP-allowlist. They return the documentUrl so a verifier can download the source PDF/markdown and re-hash it locally; any divergence flags a compromised methodology.
Why this exists
A Schema B credit-risk attestation pins methodologyHash so a verifier can cryptographically prove which underwriting scorecard a lender used at attestation time. The hash alone is opaque — these endpoints resolve it back to the source document + version + lifecycle status, completing the verifier flow.
Combined with the audit-trail trinity, this means:
- Schema B attestation carries
methodologyHash (on-chain, immutable)
GET /v2/methodologies/:lenderId/:hash resolves it to documentUrl + version + lifecycle status
SUPERSEDED / REVOKED status indicates the methodology is no longer in force — verifier-side policy decides whether to honor historical attestations
- Operator-side audit log (SUPER_ADMIN) preserves the full lifecycle for regulator review
Endpoint 1 — current ACTIVE methodology
GET /v2/methodologies/:lenderId/active
Returns the methodology document currently in force for new Schema B mints by this lender. Returns { found: false } when the lender has never registered a methodology (callers should fall back to the v0 well-known constant).
Request
| Param | Type | Notes |
|---|
lenderId | string | Kebab-case, matches ^[a-z0-9_-]{3,64}$ |
Response (200, found)
{
"found": true,
"lenderId": "crediblex-uae",
"version": "2.1.0",
"methodologyHash": "1f8b3c…",
"documentUrl": "https://crediblex.example.com/methodology/v2.1.0.pdf",
"displayName": "CredibleX UAE — SME Working-Capital Methodology v2.1",
"status": "ACTIVE",
"effectiveAt": "2026-05-01T00:00:00Z"
}
Response (200, not registered)
{ "found": false, "lenderId": "some-lender" }
Endpoint 2 — lookup by hash (verifier flow)
GET /v2/methodologies/:lenderId/:methodologyHash
The canonical verifier path. Given a lenderId + methodologyHash parsed from an on-chain Schema B attestation, resolve it back to the source document.
Request
| Param | Type | Notes |
|---|
lenderId | string | Kebab-case |
methodologyHash | string | 64-char lowercase hex (SHA-256 of the source document) |
Response (200, found)
{
"found": true,
"lenderId": "crediblex-uae",
"version": "1.0.0",
"methodologyHash": "a91d…",
"documentUrl": "https://crediblex.example.com/methodology/v1.0.0.pdf",
"displayName": "CredibleX UAE — SME Working-Capital Methodology v1.0",
"status": "SUPERSEDED",
"effectiveAt": "2026-02-01T00:00:00Z",
"supersededAt": "2026-05-01T00:00:00Z"
}
status values: ACTIVE | SUPERSEDED | REVOKED. A verifier seeing SUPERSEDED on an attestation issued before supersededAt should still honor it (the methodology was in force at mint time); seeing REVOKED is a red flag and verifier-side policy decides whether to honor.
Response (200, not found)
{
"found": false,
"lenderId": "crediblex-uae",
"methodologyHash": "00…"
}
List all versions for a lender
GET /v2/methodologies/:lenderId/versions
Returns the full versioned lineage of methodology documents this lender has ever registered — ACTIVE, SUPERSEDED, and REVOKED — sorted newest-first by effectiveAt. Verifiers use this when they want to walk a lender’s methodology history without already knowing specific methodologyHash values upfront (e.g. “show me every version CredibleX has ever published” for a regulator audit).
This endpoint is public — no JWT, no IP-allowlist. The response is intentionally redacted to a verifier-safe whitelist. Operator-only fields are deliberately NOT in the response: notes (operator-only free-text), createdBy, updatedBy, and any internal lifecycle metadata. lenderId appears once in the envelope and is omitted from each row to avoid redundant payload.
Request
| Param | Type | Notes |
|---|
lenderId | string | Kebab-case, matches ^[a-z0-9_-]{3,64}$ |
No query parameters. The response is capped at 100 versions (hard cap — older versions are not paginated; a lender publishing >100 methodology versions is a registry-design escalation, not a paging escalation).
Response (200)
{
"lenderId": "crediblex-uae",
"count": 3,
"versions": [
{
"version": "2.1.0",
"methodologyHash": "1f8b3c…",
"documentUrl": "https://crediblex.example.com/methodology/v2.1.0.pdf",
"displayName": "CredibleX UAE — SME Working-Capital Methodology v2.1",
"status": "ACTIVE",
"effectiveAt": "2026-05-01T00:00:00Z",
"supersededAt": null
},
{
"version": "2.0.0",
"methodologyHash": "b2e4f1…",
"documentUrl": "https://crediblex.example.com/methodology/v2.0.0.pdf",
"displayName": "CredibleX UAE — SME Working-Capital Methodology v2.0",
"status": "SUPERSEDED",
"effectiveAt": "2026-03-15T00:00:00Z",
"supersededAt": "2026-05-01T00:00:00Z"
},
{
"version": "1.0.0",
"methodologyHash": "a91d…",
"documentUrl": "https://crediblex.example.com/methodology/v1.0.0.pdf",
"displayName": "CredibleX UAE — SME Working-Capital Methodology v1.0",
"status": "SUPERSEDED",
"effectiveAt": "2026-02-01T00:00:00Z",
"supersededAt": "2026-03-15T00:00:00Z"
}
]
}
Field reference
| Field | Type | Notes |
|---|
lenderId | string | Envelope only; not duplicated per row |
count | integer | Total versions returned (≤ 100 hard cap) |
versions[].version | string | Lender-published semantic version (e.g. 2.1.0) |
versions[].methodologyHash | string | 64-char lowercase hex (SHA-256 of source document) |
versions[].documentUrl | string | URL of the source PDF/markdown — verifiers re-hash to confirm integrity |
versions[].displayName | string | Human-readable label |
versions[].status | enum | ACTIVE | SUPERSEDED | REVOKED |
versions[].effectiveAt | ISO 8601 | When this version went into force |
versions[].supersededAt | ISO 8601 | null | When this version was superseded; null for the current ACTIVE row |
Sort order
Versions are returned newest-first by effectiveAt — the current ACTIVE row (if any) is row 0; the lender’s earliest registration is the last row.
Curl example
curl -s https://apiv3.droplinked.com/v2/methodologies/crediblex-uae/versions | jq .
When to use this vs. the by-hash / active endpoints
- Use
GET /v2/methodologies/:lenderId/active (Endpoint 1 above) when you already know the lender and just want the current in-force methodology.
- Use
GET /v2/methodologies/:lenderId/:methodologyHash (Endpoint 2 above) when you have a specific methodologyHash from a Schema B attestation and want to resolve it to its source document.
- Use this
versions endpoint when you want the full lineage without a specific hash in hand — for example, regulator audits asking “show me every methodology this lender has ever issued attestations against.”
MCP wrapper
Consumer agents reach this endpoint via the get_methodology_versions MCP tool (in flight as a separate droplinked-mcp PR — will be listed on the Lender Trinity MCP Tools page once shipped) so ChatGPT / Claude / OpenAI Agents SDK callers can walk a lender’s methodology lineage without prior knowledge of the path scheme.
Verifier integrity check
A complete verifier flow:
# 1. Read the on-chain attestation
LENDER=$(curl -s https://apiv3.droplinked.com/v2/attestations/credit-risk/$MERCHANT \
| jq -r '.attestation.lenderId')
HASH=$(curl -s https://apiv3.droplinked.com/v2/attestations/credit-risk/$MERCHANT \
| jq -r '.attestation.methodologyHash')
# 2. Resolve methodology + download source
DOC_URL=$(curl -s https://apiv3.droplinked.com/v2/methodologies/$LENDER/$HASH \
| jq -r '.documentUrl')
curl -sLo /tmp/methodology.pdf "$DOC_URL"
# 3. Re-hash locally and compare
LOCAL=$(shasum -a 256 /tmp/methodology.pdf | awk '{print $1}')
[ "$LOCAL" = "$HASH" ] && echo "verified" || echo "TAMPERED"
If the local hash diverges from the on-chain hash, the methodology document at documentUrl was modified after the attestation was issued — flag and refuse.
Cross-reference
Discovery
The MCP server advertises this endpoint via the discovery doc at mcp.droplinked.com/.well-known/mcp.json under the verify_methodology tool, so consumer agents (ChatGPT, Claude, OpenAI Agents SDK) reach it without any prior knowledge of the path scheme.
Lifecycle timeline
GET /v2/methodologies/:lenderId/:methodologyHash/timeline
Returns the whitelist-redacted lifecycle history of a single methodology version (keyed by lenderId + methodologyHash) — used by third-party verifiers asking the temporal question: was this methodology version ACTIVE at the time a Schema B attestation was minted, or was it already SUPERSEDED / REVOKED? The point-in-time status from GET /v2/methodologies/:lenderId/:methodologyHash only answers right now; the timeline lets a verifier replay state at the attestation’s occurredAt.
This endpoint is public — no JWT, no IP-allowlist. The response is intentionally redacted to a verifier-safe whitelist. The following operator-only fields are deliberately NOT in the response: actorId (which admin made the change), reason (free-text justification), and raw before/after value diffs for metadata-change events (display name, document URL, notes, semantic version). Only previousStatus / newStatus are exposed, and only for METHODOLOGY_REGISTERED + METHODOLOGY_SUPERSEDED + METHODOLOGY_REVOKED events.
Request
| Param | Type | Notes |
|---|
lenderId | string | Kebab-case, matches ^[a-z0-9_-]{3,64}$ |
methodologyHash | string | 64-char lowercase hex (SHA-256 of the source document) |
Response (200)
{
"lenderId": "crediblex-uae",
"methodologyHash": "a91d…",
"count": 3,
"events": [
{
"occurredAt": "2026-05-01T00:00:00Z",
"eventType": "METHODOLOGY_SUPERSEDED",
"previousStatus": "ACTIVE",
"newStatus": "SUPERSEDED"
},
{
"occurredAt": "2026-03-15T10:30:00Z",
"eventType": "METHODOLOGY_DISPLAY_NAME_CHANGED",
"previousStatus": null,
"newStatus": null
},
{
"occurredAt": "2026-02-01T00:00:00Z",
"eventType": "METHODOLOGY_REGISTERED",
"previousStatus": null,
"newStatus": "ACTIVE"
}
]
}
Events are ordered newest-first and capped at 500 events per response (hard cap — older events are not paginated).
Event types
eventType | Carries previousStatus / newStatus? |
|---|
METHODOLOGY_REGISTERED | previousStatus: null, newStatus: "ACTIVE" |
METHODOLOGY_SUPERSEDED | both set (ACTIVE → SUPERSEDED) |
METHODOLOGY_REVOKED | both set (typically ACTIVE or SUPERSEDED → REVOKED) |
METHODOLOGY_DISPLAY_NAME_CHANGED | both null |
METHODOLOGY_DOCUMENT_URL_CHANGED | both null |
METHODOLOGY_NOTES_CHANGED | both null |
METHODOLOGY_VERSION_CHANGED | both null |
previousStatus / newStatus values are drawn from the lifecycle enum: ACTIVE | SUPERSEDED | REVOKED. For metadata-change events the raw before/after values are intentionally redacted — verifiers can confirm that a change occurred at occurredAt but cannot read the operator-only diff (use the source-document re-hash flow from Verifier integrity check above to detect document-content tampering).
Verifier policy
The point of the timeline is to let a verifier decide whether a methodology was in force at the moment the on-chain attestation was minted:
SUPERSEDED at check time, but ACTIVE at the attestation’s occurredAt → legitimate. The methodology was the lender’s current scorecard when they signed; the supersession is a forward-looking change. The lifecycle is monotonic in the verifier-friendly direction: ACTIVE events strictly precede SUPERSEDED events for the same version.
REVOKED at any point → red flag. Revocation indicates the methodology was withdrawn (e.g. flawed risk model, compliance issue). Verifier-side policy decides whether to honor historical attestations against a revoked methodology; the default agent posture is to flag and surface for human review.
Curl example
curl -s https://apiv3.droplinked.com/v2/methodologies/crediblex-uae/a91d…/timeline | jq .
MCP wrapper
Consumer agents reach this endpoint via the get_methodology_timeline MCP tool — already live on mcp.droplinked.com — so ChatGPT / Claude / OpenAI Agents SDK callers can replay a methodology’s lifecycle without prior knowledge of the path scheme.