PRIV ProtocolPRIV Docs
API Reference

Labeling Tasks API

Complete data labeling tasks and earn PRIV tokens with the PRIV Protocol Tasks API.

The Labeling Tasks API allows users to discover and complete AI training tasks to earn PRIV tokens. Tasks include image classification, text annotation, audio transcription, and more.

Task availability depends on your reputation level. Higher levels unlock more valuable tasks.

Get Available Tasks

GET/api/v1/tasks

Get available labeling tasks for the authenticated user. Tasks are filtered by reputation level.

Query Parameters

ParameterTypeRequiredDescription
typestringNoFilter by task type (see below)
limitnumberNoResults per page (default: 10, max: 50)
offsetnumberNoPagination offset (default: 0)

Task Types

TypeDescriptionMin Level
image_classificationClassify images into categories1
image_taggingAdd tags/labels to images1
text_sentimentClassify text sentiment1
text_annotationAnnotate text with labels2
audio_transcriptionTranscribe audio clips2
bounding_boxDraw bounding boxes on images3
semantic_segmentationPixel-level image labeling4
video_annotationAnnotate video frames4

Response

{
  "success": true,
  "data": {
    "tasks": [
      {
        "id": "task_abc123",
        "title": "Classify Vehicle Images",
        "description": "Classify images of vehicles into car, truck, motorcycle, or bicycle categories.",
        "task_type": "image_classification",
        "reward_priv": 0.50,
        "estimated_time_seconds": 30,
        "min_reputation_level": 1,
        "current_submissions": 45,
        "max_submissions": 100,
        "expires_at": "2024-01-20T00:00:00Z",
        "created_at": "2024-01-15T10:00:00Z"
      },
      {
        "id": "task_def456",
        "title": "Tag Product Images",
        "description": "Add relevant tags to e-commerce product images.",
        "task_type": "image_tagging",
        "reward_priv": 0.75,
        "estimated_time_seconds": 45,
        "min_reputation_level": 1,
        "current_submissions": 20,
        "max_submissions": 50,
        "expires_at": null,
        "created_at": "2024-01-14T08:00:00Z"
      }
    ],
    "total": 25,
    "limit": 10,
    "offset": 0,
    "user_reputation_level": 2
  }
}

Response Fields

FieldTypeDescription
idstringUnique task identifier
titlestringHuman-readable task title
descriptionstringDetailed task instructions
task_typestringType of labeling task
reward_privnumberPRIV reward for completion
estimated_time_secondsnumberEstimated time to complete
min_reputation_levelnumberMinimum reputation level required
current_submissionsnumberNumber of submissions received
max_submissionsnumberMaximum submissions allowed (null = unlimited)
expires_atstringTask expiration (null = no expiration)

Example

curl "https://api.priv.io/v1/tasks?type=image_classification&limit=20" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Get Task Details

GET/api/v1/tasks/:id

Get detailed information about a specific task including the data to label.

Path Parameters

ParameterTypeRequiredDescription
idstringYesTask UUID

Response

{
  "success": true,
  "data": {
    "task": {
      "id": "task_abc123",
      "title": "Classify Vehicle Images",
      "description": "Classify images of vehicles into categories.",
      "instructions": "Look at each image and select the most appropriate vehicle category. If the image doesn't contain a vehicle or is unclear, select 'Other'.",
      "task_type": "image_classification",
      "reward_priv": 0.50,
      "estimated_time_seconds": 30,
      "min_reputation_level": 1,
      "data": {
        "image_url": "https://storage.priv.io/tasks/task_abc123/image.jpg",
        "options": [
          { "id": "car", "label": "Car" },
          { "id": "truck", "label": "Truck" },
          { "id": "motorcycle", "label": "Motorcycle" },
          { "id": "bicycle", "label": "Bicycle" },
          { "id": "other", "label": "Other/Not a vehicle" }
        ]
      },
      "validation_info": {
        "requires_consensus": true,
        "min_consensus_rate": 0.7,
        "validators_needed": 3
      }
    },
    "can_submit": true,
    "already_submitted": false
  }
}

Submit Task Answer

POST/api/v1/tasks/:id/submit

Submit an answer for a labeling task.

Path Parameters

ParameterTypeRequiredDescription
idstringYesTask UUID

Request Body

{
  "answer": {
    "classification": "car",
    "confidence": "high"
  },
  "time_spent_ms": 15000
}

Request Fields

FieldTypeRequiredDescription
answerobjectYesTask-specific answer data
time_spent_msnumberNoTime spent on task in milliseconds

Answer Formats by Task Type

Image Classification:

{ "classification": "category_id" }

Image Tagging:

{ "tags": ["tag1", "tag2", "tag3"] }

Text Sentiment:

{ "sentiment": "positive" | "negative" | "neutral" }

Bounding Box:

{
  "boxes": [
    { "x": 100, "y": 50, "width": 200, "height": 150, "label": "car" }
  ]
}

Response

{
  "success": true,
  "data": {
    "submission_id": "sub_xyz789",
    "is_gold_standard_test": false,
    "message": "Your submission has been recorded and will be validated by other users."
  }
}

Gold Standard Response

If the submission was a gold standard test:

{
  "success": true,
  "data": {
    "submission_id": "sub_xyz789",
    "is_gold_standard_test": true,
    "gold_standard_correct": true,
    "priv_earned": 0.05,
    "message": "Great work! Your answer matched our quality standards. Bonus PRIV awarded!"
  }
}

Gold standard tests are inserted randomly (about 10% of tasks) to verify labeler accuracy. Passing them awards bonus PRIV and improves your accuracy score.

Example

curl -X POST "https://api.priv.io/v1/tasks/task_abc123/submit" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "answer": {"classification": "car"},
    "time_spent_ms": 12500
  }'

Get Task History

GET/api/v1/tasks/history

Get your task submission history and earnings.

Query Parameters

ParameterTypeRequiredDescription
limitnumberNoResults per page (default: 10, max: 100)
offsetnumberNoPagination offset (default: 0)
start_datestringNoFilter by start date (YYYY-MM-DD)
end_datestringNoFilter by end date (YYYY-MM-DD)

Response

{
  "success": true,
  "data": {
    "history": [
      {
        "id": "sub_xyz789",
        "task_id": "task_abc123",
        "task_title": "Classify Vehicle Images",
        "task_type": "image_classification",
        "status": "approved",
        "priv_earned": 0.50,
        "submitted_at": "2024-01-15T10:30:00Z",
        "validated_at": "2024-01-15T12:00:00Z"
      },
      {
        "id": "sub_abc123",
        "task_id": "task_def456",
        "task_title": "Tag Product Images",
        "task_type": "image_tagging",
        "status": "pending",
        "priv_earned": null,
        "submitted_at": "2024-01-15T11:00:00Z",
        "validated_at": null
      }
    ],
    "summary": {
      "total_submissions": 150,
      "approved": 140,
      "pending": 8,
      "rejected": 2,
      "total_priv_earned": 75.50
    },
    "pagination": {
      "total": 150,
      "limit": 10,
      "offset": 0
    }
  }
}

Submission Status

StatusDescription
pendingAwaiting validation
approvedValidated and approved, reward credited
rejectedFailed validation, no reward

Example

curl "https://api.priv.io/v1/tasks/history?start_date=2024-01-01&end_date=2024-01-31" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

JavaScript Examples

Task Completion Flow

interface Task {
  id: string;
  title: string;
  task_type: string;
  reward_priv: number;
  data: {
    image_url?: string;
    options?: Array<{ id: string; label: string }>;
  };
}

// Fetch available tasks
async function getAvailableTasks(type?: string): Promise<Task[]> {
  const params = new URLSearchParams();
  if (type) params.set('type', type);
  params.set('limit', '20');

  const response = await fetch(
    `https://api.priv.io/v1/tasks?${params}`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );

  const data = await response.json();
  return data.data.tasks;
}

// Submit task answer
async function submitTaskAnswer(
  taskId: string,
  answer: Record<string, unknown>,
  timeSpentMs: number
) {
  const response = await fetch(
    `https://api.priv.io/v1/tasks/${taskId}/submit`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        answer,
        time_spent_ms: timeSpentMs,
      }),
    }
  );

  const data = await response.json();

  if (!data.success) {
    throw new Error(data.error.message);
  }

  return {
    submissionId: data.data.submission_id,
    isGoldStandard: data.data.is_gold_standard_test,
    passed: data.data.gold_standard_correct,
    earned: data.data.priv_earned,
  };
}

// Complete multiple tasks
async function completeTasks(count: number) {
  const tasks = await getAvailableTasks('image_classification');
  const results = [];

  for (const task of tasks.slice(0, count)) {
    const startTime = Date.now();

    // Simulate user making a selection (in real app, this comes from UI)
    const answer = { classification: task.data.options?.[0]?.id };
    const timeSpent = Date.now() - startTime;

    try {
      const result = await submitTaskAnswer(task.id, answer, timeSpent);
      results.push({ task: task.id, ...result });
    } catch (error) {
      results.push({ task: task.id, error: error.message });
    }
  }

  return results;
}

Track Earnings

async function getTaskEarnings(startDate: string, endDate: string) {
  const response = await fetch(
    `https://api.priv.io/v1/tasks/history?start_date=${startDate}&end_date=${endDate}&limit=100`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );

  const data = await response.json();
  const { history, summary } = data.data;

  console.log(`Total submissions: ${summary.total_submissions}`);
  console.log(`Approved: ${summary.approved} (${(summary.approved / summary.total_submissions * 100).toFixed(1)}%)`);
  console.log(`Total earned: ${summary.total_priv_earned} PRIV`);

  // Calculate average per approved task
  const avgPerTask = summary.total_priv_earned / summary.approved;
  console.log(`Average per task: ${avgPerTask.toFixed(2)} PRIV`);

  return { history, summary };
}

Reputation Progress Tracker

async function getProgressToNextLevel() {
  const response = await fetch(
    'https://api.priv.io/v1/user/reputation',
    { headers: { 'Authorization': `Bearer ${token}` } }
  );

  const data = await response.json();
  const rep = data.data;

  console.log(`Current Level: ${rep.reputation_level} (${rep.level_name})`);
  console.log(`Accuracy: ${(rep.accuracy_score * 100).toFixed(1)}%`);
  console.log(`Tasks Completed: ${rep.total_tasks_completed}`);

  if (rep.next_level_requirements) {
    const next = rep.next_level_requirements;
    console.log(`\nTo reach ${next.level_name}:`);
    console.log(`  - Tasks needed: ${next.tasks_needed}`);
    console.log(`  - Accuracy needed: ${(next.accuracy_needed * 100).toFixed(1)}%`);
    console.log(`  - Stake needed: ${next.stake_needed} PRIV`);
  } else {
    console.log('\nYou have reached the maximum level!');
  }

  return rep;
}

Best Practices

Maximize Earnings

  1. Maintain high accuracy - Gold standard tests and consensus validation affect your reputation and task access
  2. Complete tasks consistently - Regular activity builds reputation faster
  3. Start with easier tasks - Build accuracy on simpler tasks before attempting complex ones
  4. Track your time - Submitting time_spent_ms helps improve task estimates and may affect rewards

Avoid Common Mistakes

  1. Don't rush - Low-quality submissions hurt your accuracy score
  2. Read instructions carefully - Each task type has specific requirements
  3. Don't submit randomly - Consensus validation will catch inconsistent answers
  4. Check expiration dates - Some tasks have deadlines