AI Verification

Verify contributor proofs with AI agents

← Back to Docs

Overview

When contributors submit proof-of-work (PRs, commits, documentation) for your skills, AI verification evaluates each proof across four dimensions and assigns a contribution weight. There are two paths:

Path A: CLI Verification
Recommended

Run verification locally with your own Anthropic API key. Your key never leaves your machine. Works with Claude Code, any AI agent, or raw curl.

Path B: Server-Side (BYOK)

Store your Anthropic key in Settings and let the server verify automatically. Convenient, but your key is stored server-side.

Step 1: Get an API Token

SkillSlap uses personal API tokens (sk_live_...) for CLI and agent authentication. Pick the method that fits your workflow:

Option A — skillslap login
Easiest

One command — opens a browser tab, click Authorize, done. Token saved to disk and picked up automatically by the MCP server and CLI.

npx skillslap login
#  → Opens https://skillslap.com/auth/cli?code=...
#  → Click "Authorize"
#  ✅ Token saved to ~/.config/skillslap/credentials

Option B — Dashboard API Tokens

  1. Go to Settings → API Tokens
  2. Click New token, give it a name
  3. Copy the sk_live_... token — it's shown once only

Then set it as an environment variable wherever you use it:

export SKILLSLAP_TOKEN="sk_live_..."
# or in your MCP config's env block

Tokens are long-lived and don't expire. Revoke them any time from Settings → API Tokens.

Step 2: Verify Proofs via CLI

The workflow is: fetch pending proofs evaluate with AI post results back.

Claude Code

Paste this prompt into Claude Code. Replace placeholder values with your data.

I need you to verify pending contribution proofs for my SkillSlap projects.

1. Fetch my pending proofs:
   curl -H "Authorization: Bearer $SKILLSLAP_TOKEN" \
     https://skillslap.com/api/proofs/pending

2. For each proof in the response, evaluate it against the skill context.
   Score each proof on 4 dimensions (0.0 to 1.0):
   - relevance: Is this contribution relevant to the skill?
   - quality: How substantive and thorough is the work?
   - evidence: How strong is the proof (URL, description)?
   - impact: What impact does this have on the skill's value?

3. Post each result back:
   curl -X POST \
     -H "Authorization: Bearer $SKILLSLAP_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"scores":{"relevance":0.9,"quality":0.8,"evidence":0.7,"impact":0.6},"reasoning":"..."}' \
     https://skillslap.com/api/proofs/<PROOF_ID>/verify-result

Any Agent (curl)

Raw curl commands for any terminal or scripting environment.

1. Fetch pending proofs:

TOKEN="$SKILLSLAP_TOKEN"   # or paste sk_live_... directly
BASE="https://skillslap.com"

curl -s -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/proofs/pending" | jq .

2. Post verification result:

PROOF_ID="uuid-of-the-proof"

curl -s -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scores": {
      "relevance": 0.9,
      "quality": 0.85,
      "evidence": 0.7,
      "impact": 0.8
    },
    "reasoning": "Strong PR with tests. Directly improves the skill."
  }' \
  "$BASE/api/proofs/$PROOF_ID/verify-result" | jq .

Custom Script (Node.js)

Complete Node.js script using @anthropic-ai/sdk to fetch, evaluate, and post results automatically.

import Anthropic from "@anthropic-ai/sdk";

const BASE = "https://skillslap.com";
const TOKEN = process.env.SKILLSLAP_TOKEN;  // sk_live_...
const anthropic = new Anthropic();          // uses ANTHROPIC_API_KEY env var

async function main() {
  const res = await fetch(`${BASE}/api/proofs/pending`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
  });
  const { proofs } = await res.json();

  if (!proofs?.length) { console.log("No pending proofs."); return; }

  for (const proof of proofs) {
    console.log(`Evaluating proof ${proof.id}...`);

    const message = await anthropic.messages.create({
      model: "claude-sonnet-4-6",
      max_tokens: 1024,
      messages: [{
        role: "user",
        content: `Evaluate this contribution proof.

Skill: ${proof.skill?.title} - ${proof.skill?.description}
Proof type: ${proof.proof_type}
Description: ${proof.description}
Evidence URL: ${proof.evidence_url || "None"}

Score on 4 dimensions (0.0-1.0): relevance, quality, evidence, impact.
Respond with JSON only: {"scores":{...},"reasoning":"..."}`
      }],
    });

    const text = message.content[0].type === "text" ? message.content[0].text : "";
    const result = JSON.parse(text);

    const postRes = await fetch(`${BASE}/api/proofs/${proof.id}/verify-result`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${TOKEN}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(result),
    });
    const outcome = await postRes.json();
    console.log(`  -> weight: ${outcome.weight_awarded}`);
  }
}

main().catch(console.error);

Scoring Rubric

Each proof is scored across 4 dimensions. The final weight is a weighted average:

DimensionWeightDescription
Relevance25%Is this contribution relevant to the skill?
Quality35%How substantive and thorough is the work?
Evidence20%How strong is the proof? (PR link, detailed description)
Impact20%What impact does this have on the skill's value?

Formula:

weight = relevance * 0.25 + quality * 0.35 + evidence * 0.20 + impact * 0.20

API Reference

GET
/api/proofs/pending

Fetch all pending (unverified) proofs for skills you own.

Auth: Authorization: Bearer sk_live_...

Response:

{
  "proofs": [
    {
      "id": "uuid",
      "skill_id": "uuid",
      "proof_type": "pull_request",
      "description": "Added error handling...",
      "evidence_url": "https://github.com/...",
      "skill": { "title": "...", "description": "...", "tags": [...] }
    }
  ]
}

POST
/api/proofs/:id/verify-result

Submit AI-computed verification scores for a proof. Skill owner only.

Auth: Authorization: Bearer sk_live_...

Request body:

{
  "scores": { "relevance": 0.9, "quality": 0.85, "evidence": 0.7, "impact": 0.8 },
  "reasoning": "Explanation of the evaluation"
}

Response (200):

{ "verified": true, "weight_awarded": 0.838, "scores": {...}, "reasoning": "..." }

Error codes: 400 invalid · 401 unauthenticated · 403 not owner · 404 not found · 409 already verified

POST
/api/skills/:id/verifications

Submit a creator or community skill verification with optional agent info.

Auth: Authorization: Bearer sk_live_...

Request body:

{
  "tier": "community",
  "execution_trace": { "steps": ["..."], "result": "passed" },
  "agent_info": {
    "model_name": "claude-sonnet-4-6",
    "model_provider": "anthropic",
    "agent_name": "Claude Code"
  }
}

POST
/api/skills/:id/verifications/system

Trigger a system verification. Owner must have an Anthropic API key configured in Settings.

Auth: skill owner only

Response (200):

{
  "id": "uuid",
  "status": "passed",
  "overall_score": 0.82,
  "security_passed": true,
  "agent_info": { "model_name": "claude-sonnet-4-6", "verified": true }
}

Skill Verification Tiers

System
Verified

AI-powered analysis using the owner's API key. Agent identity is verified from the API response.

Creator
Self-reported

Manual verification by the skill owner. Agent info is optional and self-reported.

Community
Self-reported

Any authenticated user can verify. Agent info is optional and self-reported.

Agent Self-Identification

Include agent_info in creator/community verifications for provenance tracking (optional but recommended):

{
  "model_name": "gpt-4o",           // required if agent_info provided
  "model_provider": "openai",       // required if agent_info provided
  "agent_name": "My Custom Agent",  // optional
  "agent_version": "1.2.0"          // optional
}

Path B: Server-Side Verification (BYOK)

Store your Anthropic API key on the server and let verification run automatically whenever a new proof is submitted.

  1. Go to Settings
  2. Scroll to AI Verification
  3. Enter your Anthropic API key (sk-ant-...)
  4. New proofs will be verified automatically using your key

Your key is stored encrypted. For maximum security, use CLI-based verification (Path A) instead.