@verifyugc/sdk
v1.0.0
Published
Official VerifyUGC client — blacklist checks, creator profiles, Trust Scores, the creator directory, asset/map registries, courses, vouches, deal & karma writes, similarity & link-safety tools, and the embeddable trust widget.
Maintainers
Readme
@verifyugc/sdk
Tiny, zero-dependency, fully-typed client for the VerifyUGC public API — blacklist checks, creator profiles, Trust Scores, the creator directory, the asset & map registries, courses, vouches, deal & karma writes, similarity & link-safety tools, and the embeddable trust widget. Works in browsers, Cloudflare Workers, and Node 18+.
npm install @verifyugc/sdkQuick start
import { VerifyUGC } from "@verifyugc/sdk";
const vugc = new VerifyUGC({ apiKey: "vugc_live_..." });
// Is this Roblox account blacklisted?
const hit = await vugc.checkBlacklist("roblox", "1523905");
if (hit.banned) console.log("Blocked:", hit.reason_code);
// Full Trust Score — a composite 0–250 score with a coarse band + trend
const trust = await vugc.getTrust("novaforge");
console.log(trust.trust_score, trust.band, trust.trend?.direction); // e.g. 187 "great" "up"Trust Score scale:
trust_scoreis an integer from 0 to 250 (0 = banned, ~250 = excellent). Thebandis the coarse label for that score (banned→excellent).
The constructor accepts:
| Option | Default | Notes |
| --------------- | ------------------------------------ | ------------------------------------------------ |
| apiKey | — | Required only for keyed endpoints. |
| baseUrl | https://verifyugc.dev/v1 | Keyed + keyless /v1 read APIs. |
| publicBaseUrl | https://verifyugc.dev/v1/public | The free keyless lookups. |
| fetch | globalThis.fetch | Pass a custom fetch on Node < 18 or in tests. |
Authentication
Keyed methods send Authorization: Bearer <apiKey> and reject before any network call if no key was supplied. Keyless methods need no key — construct the client with no options.
Blacklist
checkBlacklist(username) — keyless
Free unified search by username/handle — one query checked across every platform at once (alias of publicCheck). No API key needed.
const vugc = new VerifyUGC(); // no key
const r = await vugc.checkBlacklist("shadowdev");
if (r.found) r.platforms.forEach((p) => console.log(p.platform, p.reason_code));checkBlacklist(provider, id, vertical?) — keyed
Exact account lookup (requires an API key).
const hit = await vugc.checkBlacklist("roblox", "1523905", "roblox");
// { provider, id, banned, severity?, scope?, reason_code?, summary?, checked_at }batchCheck(accounts, vertical?) — keyed
Up to 100 accounts in one call; results come back in input order.
const { results } = await vugc.batchCheck([
{ provider: "roblox", id: "1523905" },
{ provider: "discord", id: "209123456789012345" },
]);
results.forEach((r) => console.log(r.id, r.banned));listBlacklist(opts?) — keyed
Cursor-paginated feed of active entries. Use since for incremental sync.
let cursor;
do {
const page = await vugc.listBlacklist({ cursor, limit: 100, vertical: "roblox" });
for (const e of page.data) console.log(e.id, e.reason_code, e.issued_at);
cursor = page.next_cursor;
} while (cursor);getBlacklistEntry(id) — keyed
const entry = await vugc.getBlacklistEntry("bl_01HX...");Creators
getProfile(handle) — keyed
const profile = await vugc.getProfile("novaforge");
// { handle, display_name, verification_level, trust_score, trust_band, reviews, ... }getTrust(handle) / getTrustScore(username, platform?) — keyed
Composite Trust Score (0–250) with the public basis and a recent trend. getTrustScore is a convenience alias of getTrust; the score is a single cross-platform composite, so platform is an optional advisory hint (reserved — not sent to the server today).
const t = await vugc.getTrustScore("novaforge");
console.log(t.trust_score, t.band, t.basis?.completed_deals);Reports
submitReport(params) — session-authenticated
File an abuse report against a creator or off-platform account. This endpoint authenticates with the logged-in VerifyUGC session cookie (not an API key), so it's meant to be called from a browser where the user is signed in — the cookie is sent automatically (credentials: "include"). Provide either subject_handle or subject_external, a category, and a description of 20–2000 characters.
const report = await vugc.submitReport({
subject_handle: "shadowdev",
category: "scam", // scam | stolen_assets | chargeback_fraud | harassment | impersonation | alt_evasion | tos_violation | other
vertical: "roblox", // optional, defaults to "all"
description: "Took a 50% deposit for a UGC commission and never delivered — DMs since ignored.",
});
console.log(report.id, report.status); // "rep_…", "pending"Deals & karma (write)
Write endpoints need a key with the matching scope (deals:write / karma:write).
Both accept an optional idempotency key — pass the same value to make a retry safe.
createDeal(params, idempotencyKey?) — keyed (deals:write)
Record a completed business deal between two members. It starts unconfirmed; each
party confirms separately. A confirmed deal feeds both parties' Trust Scores.
const deal = await vugc.createDeal({
party_a_handle: "novaforge",
party_b_handle: "studiomars",
vertical: "roblox",
summary: "UGC hat commission",
value_band: "$100–250",
}, "deal-2024-0042"); // optional idempotency key
// { id: "deal_…", status: "unconfirmed" }confirmDeal(id, confirmAs) — keyed (deals:write)
await vugc.confirmDeal(deal.id, "a");
const res = await vugc.confirmDeal(deal.id, "b");
console.log(res.confirmed); // true once both parties confirmgrantKarma(handle, delta, reason?, idempotencyKey?) — keyed (karma:write)
Grant (positive) or deduct (negative) karma; |delta| ≤ 1000.
const r = await vugc.grantKarma("novaforge", 25, "Helpful in #support");
console.log(r.karma); // new totalKeyless public lookups
No API key needed — perfect for client-side widgets and pre-deal checks.
publicTrust(handle)
Coarse Trust tier (band + label + colour). The raw numeric score is only returned to authenticated (session-cookie) callers.
const vugc = new VerifyUGC(); // no key
const t = await vugc.publicTrust("novaforge"); // { found, band, tier, tier_color, blacklisted }publicCheck(query)
Free unified blacklist search — one query checked across every platform at once.
const r = await vugc.publicCheck("shadowdev");
if (r.found) r.platforms.forEach((p) => console.log(p.platform, p.reason_code));resolve(provider, id)
Map a public linked platform account to its VerifyUGC creator + Trust Score.
const r = await vugc.resolve("roblox", "1523905");
if (r.found) console.log(r.handle, r.trust_score, r.profile_url);Creator directory
searchDirectory(query?) — keyless
Search / filter / sort / cursor-paginate the verified-creator directory.
const page = await vugc.searchDirectory({
q: "nova",
platform: "roblox", // "roblox" | "uefn" | "minecraft"
verified: true,
sort: "trust", // "newest" | "trust" | "vouches" | "deals"
});
console.log(page.total, page.items.map((i) => i.handle));
// next page
if (page.has_more) {
const next = await vugc.searchDirectory({ q: "nova", cursor: page.next_cursor });
}Asset & map registries
searchAssets(q, platform?) — keyless
Search the Asset Fingerprint Registry by name or numeric asset id (Roblox today).
const { results } = await vugc.searchAssets("neon sword");
results.forEach((a) => console.log(a.asset_name, a.owner.handle, a.verification_status));searchMaps(q, platform?) — keyless
Search the UEFN Map Chain-of-Custody Registry by name or island code.
const { results } = await vugc.searchMaps("1234-5678-9012");
results.forEach((m) => console.log(m.map_name, m.version_count, m.owner.handle));Courses
listCourses() — keyless
List creator-education courses (each locked for anonymous callers; available/passed with a session cookie).
const { courses, trust } = await vugc.listCourses();
courses.forEach((c) => console.log(c.title, c.status, `${c.points} pts`));
console.log("Trust points from courses:", trust.earned_points, "/", trust.max_points);Vouches
getVouches(handle, query?) — keyless
Public, paginated list of the peer vouches a creator has received (most recent first).
const page = await vugc.getVouches("novaforge", { limit: 20, offset: 0 });
console.log(`${page.count} total vouches`);
page.vouches.forEach((v) => console.log(v.from_username, v.message));Tools
Free, keyless, per-IP rate-limited (10/min) helpers that power the public /tools/* pages. No input is stored.
checkSimilarity(description, platform?) — keyless
Check a work description against the prior-art registries (asset + UEFN map) before you publish — a heuristic word-overlap score, not a legal ruling. platform is "roblox", "uefn"/"fortnite", or "all" (default).
const vugc = new VerifyUGC(); // no key
const r = await vugc.checkSimilarity("Neon energy sword with glowing runes", "roblox");
console.log(`${r.total_checked} works scanned`);
r.matches.forEach((m) => console.log(m.name, m.similarity_score, m.registrant_handle));checkLink(url) — keyless
Check whether a link is a known fake-verification / phishing site before you click or accept a deal link.
const r = await vugc.checkLink("https://free-robux-now.example");
console.log(r.safe, r.risk_level, r.reasons); // false, "dangerous", ["…"]
if (r.official_url) console.log("Did you mean:", r.official_url);Embed the trust widget
import { mountTrustWidget } from "@verifyugc/sdk";
mountTrustWidget("novaforge", document.getElementById("trust"));Or with a single script tag, no SDK:
<script src="https://verifyugc.dev/widget/trust.js" data-handle="novaforge" async></script>Errors
Failed requests throw VerifyUGCError with .status (HTTP code) and .body (parsed JSON). Keyed calls without an apiKey reject before hitting the network.
import { VerifyUGCError } from "@verifyugc/sdk";
try {
await vugc.getTrust("novaforge");
} catch (err) {
if (err instanceof VerifyUGCError) console.error(err.status, err.body);
}TypeScript
The package ships type declarations (dist/index.d.ts). Every method is fully typed; response interfaces (BlacklistResult, CreatorProfile, TrustResult, DirectoryPage, AssetSearchResponse, MapSearchResponse, CoursesResponse, VouchesPage, CreatedDeal, KarmaResult, SimilarityResult, LinkCheckResult, …) are exported for your own use.
License
MIT
