Submitting Data
Contributor guide for finding bounties, submitting content, and earning PRIV tokens on the Data Bounty Board.
Getting Started as a Contributor
The Data Bounty Board allows you to earn PRIV tokens by providing data that businesses need for AI training, research, and analytics.
Prerequisites
- PRIV account - Sign up at app.privlabs.io
- Connected wallet - Link your Ethereum wallet for payouts
- Age verification - Most bounties require contributors to be 18+
- Reputation building - Start with entry-level bounties to build your reputation
Finding Bounties
Browse Available Bounties
Navigate to the Data Bounty Board section to see all active bounties:
# API: Browse public bounties
curl https://api.privlabs.io/v1/b2b/requests/browse \
-H "Authorization: Bearer your_token"Filter by Type
| Filter | Description |
|---|---|
| Type | image, video, audio, voice, text, behavioral, location |
| Price Range | Minimum/maximum PRIV per submission |
| Tags | Topic keywords |
| Reputation Required | Filter by your current level |
Bounty Details
Each bounty includes:
┌─────────────────────────────────────────────────────────────────┐
│ Urban Street Photography Dataset Active │
│ by AI Vision Labs │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Type: Images Price: 0.50 PRIV per item │
│ Target: 10,000 Progress: 3,247 / 10,000 (32%) │
│ Expires: June 1, 2026 │
│ Escrow: 5,000 PRIV locked in BountyEscrow.sol │
│ │
│ Requirements: │
│ ├── Min Resolution: 1920x1080 │
│ ├── Format: JPEG │
│ ├── Reputation Level: 1+ │
│ └── Approver Voting: Yes │
│ │
│ Consent Required: │
│ ├── AI Training: Yes │
│ └── Commercial Use: Yes │
│ │
│ Tags: photography, urban, street, computer-vision │
│ │
│ [View Details] [Opt In] │
│ │
└─────────────────────────────────────────────────────────────────┘Opting Into Bounties
Before submitting data, you must opt into a bounty to confirm you meet the requirements and accept the terms.
Opt-In Process
- Review requirements - Ensure you can provide the requested data type and quality
- Check consent requirements - Understand how your data will be used
- Confirm eligibility - Verify you meet age and geographic requirements
- Accept terms - Agree to the bounty-specific terms
# API: Opt into a bounty
curl -X POST https://api.privlabs.io/v1/b2b/requests/req_a1b2c3/opt-in \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"confirmedAge": true,
"agreedToTerms": true,
"consent": {
"aiTraining": true,
"commercial": true,
"research": false
}
}'Only opt in if you can genuinely provide the requested data. Opting in and not submitting, or submitting low-quality data, affects your reputation.
Submission Requirements
File Format Guidelines
Each bounty type has specific format requirements:
Images
| Requirement | Limits |
|---|---|
| File Types | JPEG, PNG, WebP, HEIC, GIF, BMP, TIFF |
| Max File Size | 25 MB |
| Resolution | 100x100 to 10000x10000 pixels |
| Quality Score | Minimum 0.3 (auto-assessed) |
Videos
| Requirement | Limits |
|---|---|
| File Types | MP4, WebM, MOV, AVI, MKV, MPEG |
| Max File Size | 500 MB |
| Duration | 1 second to 1 hour |
| Resolution | 240p to 4K |
| FPS | 10-120 fps |
Audio
| Requirement | Limits |
|---|---|
| File Types | MP3, WAV, WebM, OGG, M4A, FLAC, AAC |
| Max File Size | 100 MB |
| Duration | 1 second to 2 hours |
| Sample Rate | 8kHz to 192kHz |
Voice Recordings
| Requirement | Limits |
|---|---|
| File Types | MP3, WAV, WebM, OGG, MP4 |
| Max File Size | 50 MB |
| Duration | 1 second to 30 minutes |
| Sample Rate | Minimum 16kHz |
| Speech Detection | Minimum 50% speech content |
Text
| Requirement | Limits |
|---|---|
| File Types | Plain text, JSON, CSV, Markdown |
| Max File Size | 5 MB |
| Character Count | 10 to 1,000,000 |
| Word Count | Minimum 3 words |
| Languages | EN, ES, FR, DE, ZH, JA, KO, PT, RU, AR |
Content Ownership
You must certify that:
- You created the content or have rights to distribute it
- No copyright violations - Content is original or properly licensed
- No third-party claims - No one else can claim ownership
Submitting Data
Step 1: Prepare Your File
Ensure your file meets all requirements before uploading:
// Client-side file preparation
const file = document.getElementById('fileInput').files[0];
// Calculate SHA-256 hash for deduplication
const hashBuffer = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());
const hashArray = Array.from(new Uint8Array(hashBuffer));
const fileHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log('File hash:', fileHash);Step 2: Upload to IPFS
Content is stored on IPFS for decentralization:
# Upload file and get CID
curl -X POST https://api.privlabs.io/v1/storage/upload \
-H "Authorization: Bearer your_token" \
-F "file=@photo.jpg"
# Response
{
"success": true,
"data": {
"cid": "QmXnnyufdzAWL5CqZ2RnSNgPbvCc1ALT73s6epPrRnZ1Xy",
"size": 2048576
}
}Step 3: Submit to Bounty
curl -X POST https://api.privlabs.io/v1/b2b/requests/req_a1b2c3/submit \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"fileHash": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"ipfsCid": "QmXnnyufdzAWL5CqZ2RnSNgPbvCc1ALT73s6epPrRnZ1Xy",
"fileSizeBytes": 2048576,
"mimeType": "image/jpeg",
"filename": "street_scene_001.jpg",
"description": "Urban street scene in downtown Tokyo",
"consent": {
"aiTraining": true,
"commercial": true,
"research": false,
"confirmedAge": true,
"agreedToTerms": true
},
"attributes": {
"width": 3840,
"height": 2160
},
"metadata": {
"camera": "Sony A7III",
"location": "Tokyo, Japan",
"date": "2026-01-15"
}
}'Response
{
"success": true,
"data": {
"submission": {
"id": "sub_x1y2z3",
"requestId": "req_a1b2c3",
"status": "pending",
"fileHash": "a1b2c3...",
"qualityScore": null,
"auditStatus": "pending",
"paymentStatus": null,
"createdAt": "2026-02-04T10:30:00Z"
},
"message": "Submission received and queued for approver voting",
"estimatedPayout": "0.425000"
}
}Submission Lifecycle
┌─────────┐ ┌────────────┐ ┌──────────┐
│ Pending │ ──> │ Validating │ ──> │ Approved │
└─────────┘ └────────────┘ └──────────┘
│ │ │
│ │ ▼
│ │ ┌──────────────┐
│ │ │ Approver │ (if required)
│ │ │ Voting │
│ │ └──────────────┘
│ │ │
│ │ ┌────────┴────────┐
│ │ ▼ ▼
│ │ Vote Passed Vote Failed
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ │
│ │ │ Escrow Payout │ │
│ │ └─────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────┐ │
│ └──> │ Paid │ │
│ └──────┘ │
│ │
└────────> Rejected <────────────────────────┘
Flagged (manual review)Tracking Submissions
View Your Submissions
curl https://api.privlabs.io/v1/b2b/submissions/my \
-H "Authorization: Bearer your_token"Submission Statuses
| Status | Description | Action |
|---|---|---|
| Pending | Received, awaiting processing | Wait |
| Validating | Being automatically checked | Wait |
| Approved | Passed validation | Waiting for approver voting or payment |
| Rejected | Failed validation | Review reason, improve |
| Flagged | Needs manual review | Wait for decision |
| Under Review | Being reviewed by staked approvers | Wait |
| Vote Passed | Approved by approver consensus | Payment processing |
| Vote Failed | Rejected by approver consensus | Review feedback |
| Payment Pending | Escrow payout being processed | Wait |
| Paid | Earnings sent to wallet from escrow | Claim from dashboard |
Earnings and Payments
Payout Calculation
Your earnings per approved submission:
Submission Price: 0.50 PRIV
├── Your Payout (97%): 0.485 PRIV
└── Protocol Fee (3%): 0.015 PRIV
With Approver Voting Premium (+25%):
├── Your Payout: 0.485 PRIV
└── Approver Reward: 0.125 PRIVClaiming Earnings
Earnings are credited to your PRIV balance instantly from escrow upon approval. Claim to your wallet:
curl -X POST https://api.privlabs.io/v1/user/earnings/claim \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"amount": "100.00",
"walletAddress": "0x..."
}'Earnings Dashboard
Track your earnings in the dashboard:
| Metric | Description |
|---|---|
| Total Earned | Lifetime earnings |
| Pending | Awaiting approval/approver voting |
| Available | Ready to claim |
| Claimed | Withdrawn to wallet |
Best Practices
Maximizing Approval Rate
- Read instructions carefully - Follow every requirement exactly
- Check sample content - Match the style and quality shown
- Review before submitting - Double-check file quality
- Provide accurate metadata - Don't guess or make up details
Avoiding Rejection
Common rejection reasons:
| Issue | Solution |
|---|---|
| Wrong format | Convert to required format |
| Low resolution | Use higher quality source |
| Contains prohibited content | Re-read prohibited list |
| Duplicate content | Only submit original work |
| Missing metadata | Fill in all required fields |
Building Reputation
| Action | Reputation Impact |
|---|---|
| Approved submission | +1 point |
| Rejected submission | -2 points |
| Flagged for fraud | -20 points + penalty |
| Consistent quality | Bonus at milestones |
Reaching Level 2 reputation unlocks staked approver privileges, allowing you to earn additional income by reviewing others' submissions.
Code Examples
JavaScript SDK Integration
import { PrivClient } from '@priv/sdk';
const priv = new PrivClient({
apiKey: process.env.PRIV_API_KEY,
});
// Browse available bounties
const bounties = await priv.b2b.requests.browse({
type: 'image',
minPrice: 0.1,
maxPrice: 1.0,
});
// Opt into a bounty
await priv.b2b.requests.optIn('req_a1b2c3', {
consent: {
aiTraining: true,
commercial: true,
research: false,
},
});
// Upload and submit
const { cid } = await priv.storage.upload(file);
const submission = await priv.b2b.requests.submit('req_a1b2c3', {
ipfsCid: cid,
fileHash: await calculateHash(file),
fileSizeBytes: file.size,
mimeType: file.type,
consent: {
aiTraining: true,
commercial: true,
research: false,
confirmedAge: true,
agreedToTerms: true,
},
});
console.log('Submission ID:', submission.id);
console.log('Estimated payout:', submission.estimatedPayout);Batch Submissions
// Submit multiple files efficiently
const files = [...document.querySelectorAll('input[type=file]')]
.flatMap(input => [...input.files]);
const submissions = await Promise.all(
files.map(async (file) => {
const { cid } = await priv.storage.upload(file);
const hash = await calculateHash(file);
return priv.b2b.requests.submit('req_a1b2c3', {
ipfsCid: cid,
fileHash: hash,
fileSizeBytes: file.size,
mimeType: file.type,
consent: defaultConsent,
});
})
);
console.log(`Submitted ${submissions.length} files`);Troubleshooting
| Issue | Solution |
|---|---|
| "You must opt in first" | Complete opt-in before submitting |
| "File hash already exists" | Content was already submitted |
| "Bounty not accepting submissions" | Bounty is paused/fulfilled/expired |
| "Insufficient reputation" | Build reputation on easier bounties |
| "Consent mismatch" | Ensure consent matches bounty requirements |
Next Steps
- Content Rules - What content is allowed
- Approver Voting - Become a staked approver
- Fraud Protection - Understand the rules