Take the first two in order. One command puts real, deterministically scored subjects in front of you in about two minutes, so nothing below starts from an empty ledger. Then the counterparty loop takes you to the thing that actually matters: an outcome someone other than the subject confirmed. Every endpoint and SDK method here is live today; each links to a runnable script.
Seed a fully isolated sandbox with synthetic subjects, scored by the identical deterministic formula. Every score endpoint returns something meaningful straight away, with nothing to invent and nothing to wait for.
curl). It creates five synthetic subjects with real outcome history, then prints the score each one earned.DELETE /api/v1/test/data wipes it.$ export CREDDA_API_KEY=crd_test_…
$ npx @credda/cli quickstart
SUBJECT SCORE BAND
sbx_reliable_courier 81 Excellent
sbx_steady_freelancer 75.5 Good
sbx_unverified_hustler 38.33 Building
sbx_breached_supplier 33.25 Unproven
sbx_new_signup 21.89 Unproven
# No CLI? One HTTP call does the same seeding:
$ curl -X POST https://api.credda.io/api/v1/test/seed \
-H "Authorization: Bearer $CREDDA_API_KEY"
# Then read one back, the same call your integration will make:
$ curl https://api.credda.io/api/v1/users/sbx_reliable_courier/score/explain \
-H "Authorization: Bearer $CREDDA_API_KEY"
The one that matters. A confirmation request is how an outcome becomes evidence: the event is written verified only when a party DISTINCT from the subject confirms it with a one-time token. Free on every plan, and it needs no events:write scope, so this is the one write path a sandbox or Starter key can complete end to end.
POST /api/v1/confirmations. This writes nothing: no event, no score. It returns a one-time confirmationToken, shown once, and a ready-made confirmUrl.confirmUrl yourself to see the hosted page, or build your own UI on previewUrl/respondUrl.isVerified: true, earned because a distinct token-holder acted. Decline writes nothing at all: the absence of a confirmation is never treated as evidence of a bad outcome.respond yourself and watch the whole loop close in one session before you wire up delivery.# 1. Propose it (your key). Nothing is on the ledger yet.
$ curl -X POST https://api.credda.io/api/v1/confirmations \
-H "Authorization: Bearer $CREDDA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId":"worker_7","eventType":"CONTRACT_FULFILLED",
"stakeLevel":"MEDIUM","transactionValue":1200,
"counterpartyRef":"ops@northside.example",
"description":"Kitchen refit at 14 Bridge St, completed 12 March."}'
{ "confirmation": { "id": "cnf_…", "status": "PENDING" },
"confirmationToken": "…", # shown ONCE
"confirmUrl": "https://api.credda.io/confirm/cnf_…?token=…",
"previewUrl": "…/api/v1/confirmations/cnf_…/preview?token=…",
"respondUrl": "…/api/v1/confirmations/cnf_…/respond" }
# 2. The counterparty decides. NO Authorization header; they hold a
# token, not an API key. Single-use.
$ curl -X POST https://api.credda.io/api/v1/confirmations/cnf_…/respond \
-H "Content-Type: application/json" \
-d '{"token":"…","decision":"confirm"}'
{ "status": "CONFIRMED", "eventId": "evt_…" } # verified, on the ledger
// SDK: the two halves, deliberately shown apart
const req = await credda.createConfirmationRequest({ … }, KEY);
const out = await counterparty.respondToConfirmation(req.confirmation.id,
req.confirmationToken,
'confirm');
# Got a book of past work? One call turns up to 100 of them into asks:
# POST /api/v1/confirmations/batch
A user hands you a Credda share token. Resolve it to a PII-free trust payload. Public, no API key.
crd_share_… token).# public, no key needed
$ curl https://api.credda.io/api/v1/verify/THEIR_SHARE_TOKEN
{ "token": "crd_share_…", "finalScore": 72, "scoreBand": "Good",
"confidence": 0.9, "verifiedPlatforms": 2, "totalEvents": 18 }
// or with the SDK
import { CreddaClient } from '@credda/js';
const credda = new CreddaClient();
const trust = await credda.resolveToken('THEIR_SHARE_TOKEN');
Drop a trust badge on a profile or listing. It renders in a shadow DOM and verifies the credential offline in the browser.
<script src="https://api.credda.io/widget/credda-widget.js" async></script>
<credda-badge token="crd_share_…"></credda-badge>
Record an engagement outcome you observed, then read the deterministic score it produced and why it moved. This is the SELF-ASSERTED path: you vouch for the outcome on your own word. It is the right shape for outcomes your system genuinely witnessed; for evidence that carries weight, use the counterparty loop above.
isVerified: true means here: you are asserting it. Verification depth, the share of a record a third party confirmed, is what moves a score into the earned bands, and only a confirmation earns it.$ curl -X POST https://api.credda.io/api/v1/events \
-H "Authorization: Bearer $CREDDA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-4821-fulfilled" \
-d '{"userId":"seller_88","eventType":"CONTRACT_FULFILLED",
"stakeLevel":"MEDIUM","isVerified":true}'
$ curl https://api.credda.io/api/v1/users/seller_88/score \
-H "Authorization: Bearer $CREDDA_API_KEY"
{ "finalScore": 41, "scoreBand": "Building", "confidence": 0.3 }
// SDK
await credda.reportEvent({ userId: 'seller_88', eventType: 'CONTRACT_FULFILLED',
stakeLevel: 'MEDIUM', isVerified: true }, KEY);
const explain = await credda.getScoreExplain('seller_88', KEY);
Ask "what would 10 verified deliveries do?" It is a read-only projection that writes nothing, and works from a blank baseline for a brand-new user id.
$ curl -X POST https://api.credda.io/api/v1/users/anyone/score/project \
-H "Authorization: Bearer $CREDDA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"events":[{"eventType":"CONTRACT_FULFILLED","isVerified":true},
{"eventType":"CONTRACT_FULFILLED","isVerified":true}]}'
{ "delta": 8.4, "current": { "finalScore": 20, "scoreBand": "Unproven" },
"projected": { "finalScore": 28, "scoreBand": "Unproven" } }
These are the fastest paths in. For the whole surface see the product map, for audience walkthroughs see use cases, and every request/response shape is in the reference. Tiers and limits are on pricing.