Kertivo Index data schema

Current schemaVersion 2. Machine-readable: /trust-index/schema.json · Markdown: /trust-index/schema.md · Data: latest.json · raw.jsonl · /trust-index/runs.

Files

Versioning

latest.json summary fields

FieldSinceTypeMeaning
generatedAtv1string (ISO 8601 UTC)When the run was built.
runv1stringRun title, e.g. "Kertivo Index #4" (#1-#2 say "x402 Trust Index #N").
rubricv1stringGrading rubric version ("v3"). Independent of schemaVersion.
payerv1string (0x address)Wallet that paid every call.
totalSpentUSDCv1numberUSDC that left the payer wallet (sum of balance deltas).
settledPaymentsv1integerRows with a verified on-chain settlement.
capsv1object {globalUSDC, perCallUSDC}Spend caps for the run.
gradeCountsv1object grade -> countRows per grade.
verdictCountsv1object verdict -> countRows per verdict.
gradeChangesv1array {idx, endpoint, change, verdict}Rows whose grade differs from the previous run.
payToChangesv1arrayRows whose live 402 payTo differs from the previous run (alert=false for rotating sellers).
needsManualReviewv1array {endpoint, reason}Schema calls a human must read before publishing (empty in a published run unless acknowledged).
previousRunv1string|nullFile the run was compared against.
resultsv1array of rowOne row per endpoint; fields below.
schemaVersionv2integerData schema version of this file (2).
schemaDocv2string (URL)This document.
totalSettledUSDCv2numberSum of row settledUSDC: USDC we saw move on-chain to sellers. Normally equals totalSpentUSDC; a gap means money left the wallet without a verified settlement (see charged_settlement_unverified rows).
subGradeCountsv2object subGrade -> countFacilitator-refused rows per sub-grade (facilitator_account, seller_requirements, facilitator_other).
thinPaidResponsesv2array {idx, endpoint, grade, flags[], detail}Settled 2xx calls whose data was thin or wrong (see row.thinData). The case a charge-on-success gateway still charges for.
deliveryv2object {paidRows, A, B, F, aRate, usableRate, basis}Headline delivery rate over paid rows only (rows where money moved: grades A, B, F). aRate = A / paidRows, usableRate = (A + B) / paidRows, 4 decimals, null with no paid rows. Dead listings (freshness never-live / went-dark) and ungraded rows are not in the denominator. Index #3 under this rule: 78 A of 87 paid = 0.8966.
freshnessCountsv2object {live, went-dark, never-live, ungraded, retired}Rows per row.freshness; retired = rows dropped by the prune plan this run (summary.retired). Listing freshness is reported separately from delivery.
moversv2object {up[], down[], wentDark[], new[], retired[], unchanged, counts}|nullGrade movement vs the previous run. Order A > B > C > F. wentDark = A/B last run, C now. retired = in the previous run, not in this one, with reason (dead_twice from the prune plan, or not_in_this_run).
retiredv2array {endpoint, reason, evidence[]}Rows deliberately dropped from this run's sample by the prune plan (graded C this run and bad in a second observation), so they don't silently vanish.

Row fields (latest.json results[] and raw.jsonl)

FieldSinceTypeMeaning
idxv1integerRow number in this run (selection order).
cohortv1stringSelection batch the endpoint came in with (pilot, new, added-#3, added-#4, self, ...).
endpointv1string (URL)Resource URL as listed (join key across runs).
servicev1stringSeller/service name.
categoryv1stringRough category.
timestampv1string (ISO)When the paid attempt started (or the probe, if not paid).
requestv1object {url, method, body}Exactly what we sent.
replayv1objectReplayable request: method, url, headers, body, curlUnpaid (reproduces the unpaid 402), howToPay.
verdictv1enumWhat happened, separate from the grade. v2 note: a 402 answering our payment with a facilitator error code relayed only in the 402 body's error field (e.g. invalid_payment_requirements) now also counts as paid_attempt_failed_facilitator_refused (before: paid_attempt_rejected_402). Same C grade either way; no Index #1-#3 row is affected. Values: paid_ok, paid_no_delivery, charged_settlement_unverified, paid_attempt_failed_facilitator_refused, paid_attempt_rejected_402, paid_attempt_network_error, paid_attempt_failed_other, unpaid_probe_not_402, unparseable_402, no_base_usdc_option, skipped_by_cap_or_policy, not_attempted, probe_error.
unpaid402v1object {status, ms, x402Version, source, valid, amount, payTo, maxTimeoutSeconds}The unpaid probe and the Base USDC option we paid against.
priceUSDCv1number|nullListed price from the live 402.
paidTxHashv1string|nullSettlement tx (Base).
onchainv1object|nullReceipt check: status, block, transferFound, value (atomic USDC), txHash.
settledv1booleanA USDC Transfer from payer to payTo was found in a successful tx.
balanceDeltaAtomicv1string|nullPayer balance change around the call (atomic USDC, 6 decimals).
httpStatusv1integer|nullHTTP status of the paid response (200 after an async poll that delivered).
latencyMsv1integer|nullPaid call latency (end to end for async).
latencyThresholdMsv1integerSlow threshold: the 402's maxTimeoutSeconds, else 5 s.
latencyThresholdSourcev1stringWhere the threshold came from.
within5sv1booleanlatencyMs <= 5000.
schemaCheckv1enum y|partial|nAdvertised output example paths present: y >= 80%, partial > 0, n none / no 200.
schemaNotev1stringHuman-readable schema result.
schemaSourcev1enum auto|manual|auto-manual-review-needed|noneWho judged the schema.
schemaAutoCoveragev1number|nullShare of example paths present (0-1).
bodyBytesv1integer|nullPaid response size.
bodyFilev1stringArchive path of the full body.
responseBodyTruncatedInRowv1booleanraw.jsonl responseBody was cut at 20,000 chars.
gradev1enum A|B|F|C-went-dark|C-never-live|ungradedRubric v3 grade (unchanged since v2 thresholds).
everDeliveredv1booleanDelivered now or in any earlier run (decides C-went-dark vs C-never-live).
prevGradev1string|nullGrade in the previous run.
gradeChangev1string|null"X -> Y" when the grade changed.
pilotGradev1string|nullGrade in the Index #1 pilot.
priorAttemptsv1any|nullEarlier attempts recorded in the run state.
notev1string|nullRunner notes.
asyncv1object|nullAsync poll record (202 queue -> statusUrl -> completed body).
paidStatusImmediatev1integer|nullHTTP status before an async poll.
guardsv1object|nullGrader guards applied (e.g. sig0xFixed).
payToChange (optional)v1objectPresent when the live payTo differs from the previous run or selection.
payToRotates (optional)v1trueSeller uses per-request deposit addresses.
payToRotatesEvidence (optional)v1stringEvidence for payToRotates.
rubricv1stringRubric version for this row.
settledUSDCv2numberUSDC that actually moved on-chain for this call: the Transfer value in the settle tx (onchain.value / 1e6). 0 when nothing verifiably moved. Check it on Basescan with paidTxHash.
refusalv2object {side, code, label, fixIn}|nullOnly on paid_attempt_failed_facilitator_refused rows: the facilitator error string classified. side = facilitator_account (billing/account side, e.g. CDP payment-method-required; fix in the facilitator portal), seller_requirements (the requirements the seller sent were rejected, e.g. invalid_payment_requirements; fix in the seller's code), or facilitator_other (not classifiable). code = the matched error code.
subGradev2enum facilitator_account|seller_requirements|facilitator_other|nullrefusal.side, flat for filtering. The letter grade stays C; the sub-grade says who has to fix it.
thinDatav2object {flags[], problems, detail}|nullOnly on settled 2xx rows (null otherwise). flags: empty_body, non_json_body, missing_advertised_fields, error_in_2xx (error/success:false/ok:false/status error inside a 2xx), empty_result (an array the seller's example shows filled came back empty), slow (over latencyThresholdMs). detail.weakAdvertisedSchema notes an example with at most one field (a match proves little).
freshnessv2enum live|went-dark|never-live|ungradedListing freshness, separate from the delivery grade. live = a payment settled this run (grade A, B or F); went-dark = grade C-went-dark (delivered in an earlier run, nothing this run); never-live = grade C-never-live (never delivered in any run we saw; may still answer a valid unpaid 402, see unpaid402.valid); ungraded = not attempted. Retired listings are not rows; they are in summary.retired.
lastSeenLivev2string (ISO)|nullLast time we saw this listing live: this row's timestamp when live, else the previous run's lastSeenLive, else the previous run's timestamp if it was paid then (A/B/F). null = unknown or never (e.g. delivered only in the pre-#2 pilot, which has no per-row time).
lastProbeOkv2string (ISO)|nullTime of the most recent VALID unpaid 402 we saw for this listing (x402 v2 with a Base USDC exact option carrying amount, payTo and maxTimeoutSeconds; same test as unpaid402.valid), null if never. This run: when the unpaid probe answered (runner probeAt; for states recorded before probeAt existed, the row start time, which the probe follows within a second). If this run's probe failed: the previous run's lastProbeOk, else the previous run's row timestamp when its unpaid402 was valid. Shown first in the Freshness column with its age, so buyers can discount stale rows. Independent of lastSeenLive (last settled + delivered).
responseBodySha256v2string (hex)|nullIndex #4 on: sha256 of the exact bytes of the archived paid response body (bodyFile; for async deliveries, the completed body we graded). Lets anyone holding the body recheck a disputed grade without re-probing or re-paying. null when no body was saved.
schemaSnapshotSha256v2string (hex)|nullIndex #4 on: sha256 of the canonical JSON (keys sorted at every depth, no whitespace) of the advertised schema we graded against: {liveOutputSchema, output, schema} as stored in raw.jsonl schemaSnapshot. Same advertised schema = same hash, so a later listing change is detectable. null when the seller advertised nothing.

raw.jsonl only

FieldSinceTypeMeaning
responseBodyv1stringPaid response body, up to 20,000 chars.
settlev1object|nullDecoded PAYMENT-RESPONSE settle header (facilitator errorReason lives here).
schemaVersionv2integerData schema version of this line (2). Missing = 1.
schemaSnapshotv2object|nullIndex #4 on: the advertised schema we graded against: output (listing output block: example, asyncPoll), schema (listing schema), liveOutputSchema (outputSchema from the live 402, if sent), plus canonicalBytes, judgedPaths (sorted paths the schema check used) and judgedPathsSource. Hash in row.schemaSnapshotSha256.

Frozen history rows (runs/<n>.jsonl)

FieldSinceTypeMeaning
runv1integerRun number.
runAtv1string (ISO)When the row was paid (or the run time).
endpointv1string (URL)Resource URL.
servicev1string|nullSeller/service name.
categoryv1string|nullCategory.
gradev1string|nullGrade in that run.
priceUSDCv1number|nullListed price.
payTov1string|nullpayTo from the 402.
paidTxHashv1string|nullSettlement tx.
settledv1booleanVerified on-chain settlement.
httpStatusAfterPayv1integer|nullHTTP status after paying.
latencyMsv1integer|nullPaid latency.
schemaCheckv1string|nully / partial / n.
settledUSDC (optional)v2numberRun #4 on: USDC that moved on-chain for this call (0 = none). Absent in runs 1-3 (frozen).
subGrade (optional)v2stringRun #4 on, only on facilitator-refused rows: facilitator_account | seller_requirements | facilitator_other.
freshness (optional)v2stringRun #4 on: live | went-dark | never-live | ungraded. Absent in runs 1-3 (frozen).
lastSeenLive (optional)v2string (ISO)|nullRun #4 on: see row.lastSeenLive. Absent in runs 1-3 (frozen).
lastProbeOk (optional)v2string (ISO)|nullRun #4 on: see row.lastProbeOk. Absent in runs 1-3 (frozen).
responseBodySha256 (optional)v2string (hex)|nullRun #4 on: see row.responseBodySha256. Absent in runs 1-3 (frozen).
schemaSnapshotSha256 (optional)v2string (hex)|nullRun #4 on: see row.schemaSnapshotSha256. Absent in runs 1-3 (frozen).