Wallet Marketplace API
Buy and sell data wallet contents on the PRIV Protocol marketplace.
The Wallet Marketplace allows users to sell their approved contributions and purchase data from other users. All transactions are conducted in PRIV tokens.
Browse Listings
/api/v1/marketplace/wallet/listingsBrowse available data wallet listings. Supports anonymous browsing with optional authentication.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
category | string | No | Filter by category: photo, video, voice, text, mixed |
minPrice | number | No | Minimum price in PRIV |
maxPrice | number | No | Maximum price in PRIV |
sort | string | No | Sort order (see below) |
page | number | No | Page number (default: 1) |
limit | number | No | Results per page (default: 20, max: 100) |
Sort Options
| Value | Description |
|---|---|
newest | Most recently created (default) |
oldest | Oldest first |
price_low | Lowest price first |
price_high | Highest price first |
most_sales | Most purchases first |
highest_rated | Highest rated first |
Response
{
"success": true,
"data": {
"listings": [
{
"id": "listing_abc123",
"title": "Nature Photography Collection",
"description": "50 high-quality nature photos suitable for AI training",
"category": "photo",
"tags": ["nature", "outdoor", "landscape"],
"price_priv": 25.00,
"status": "active",
"contribution_count": 50,
"total_file_size_bytes": 125000000,
"preview_samples": [
{
"contribution_type": "photo",
"preview_url": "/api/v1/contributions/contrib_xyz/preview",
"metadata_preview": {}
}
],
"seller": {
"id": "usr_seller123",
"display_name": "DataProvider_a7x2",
"rating": 4.8,
"total_sales": 15,
"member_since": "2023-06-01T00:00:00Z",
"verified": true
},
"total_sales": 12,
"average_rating": 4.7,
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
],
"pagination": {
"total": 150,
"page": 1,
"limit": 20,
"total_pages": 8
}
}
}Example: Browse with Filters
curl "https://api.priv.io/v1/marketplace/wallet/listings?category=photo&maxPrice=50&sort=highest_rated" \
-H "Authorization: Bearer pk_live_xxx"Create Listing
/api/v1/marketplace/wallet/listingsCreate a new listing from your approved contributions. Requires authentication.
Request Body
{
"title": "Nature Photography Collection",
"description": "50 high-quality nature photos suitable for AI training. Includes outdoor landscapes, wildlife, and botanical images.",
"category": "photo",
"tags": ["nature", "outdoor", "landscape", "wildlife"],
"price_priv": 25.00,
"contribution_ids": [
"contrib_abc123",
"contrib_def456",
"contrib_ghi789"
]
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Listing title (max 100 chars) |
description | string | Yes | Detailed description (max 2000 chars) |
category | string | Yes | Category: photo, video, voice, text, mixed |
tags | string[] | No | Tags for discoverability (max 10) |
price_priv | number | Yes | Price in PRIV tokens |
contribution_ids | string[] | Yes | Array of contribution UUIDs to include |
All contributions must be approved and have commercial consent enabled.
Response
{
"success": true,
"data": {
"listing_id": "listing_abc123",
"status": "draft",
"contribution_count": 50,
"preview_generated": true,
"message": "Listing created as draft. Update status to pending_review when ready to publish."
}
}Listing Status Flow
draft -> pending_review -> active
-> rejected
active -> paused -> active
-> delistedExample
curl -X POST "https://api.priv.io/v1/marketplace/wallet/listings" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"title": "Nature Photography Collection",
"description": "50 high-quality nature photos",
"category": "photo",
"price_priv": 25.00,
"contribution_ids": ["contrib_abc123", "contrib_def456"]
}'Get Listing Details
/api/v1/marketplace/wallet/listings/:idGet detailed information about a specific listing.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Listing UUID |
Response
{
"success": true,
"data": {
"listing": {
"id": "listing_abc123",
"title": "Nature Photography Collection",
"description": "50 high-quality nature photos suitable for AI training",
"category": "photo",
"tags": ["nature", "outdoor"],
"price_priv": 25.00,
"status": "active",
"contribution_count": 50,
"total_file_size_bytes": 125000000,
"preview_samples": [...],
"seller": {...},
"total_sales": 12,
"average_rating": 4.7,
"sample_cids": ["Qm...", "Qm..."],
"contribution_types_breakdown": {
"photo": 50
},
"consent_info": {
"ai_training": true,
"research": true,
"commercial": true
},
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
},
"is_owner": false,
"already_purchased": false
}
}Update Listing
/api/v1/marketplace/wallet/listings/:idUpdate a listing you own. Only certain fields can be updated based on status.
Request Body
{
"title": "Updated Title",
"description": "Updated description",
"price_priv": 30.00,
"status": "pending_review",
"tags": ["nature", "outdoor", "new-tag"]
}Updatable Fields
| Field | Can Update When |
|---|---|
title | draft, paused |
description | draft, paused |
price_priv | draft, paused, active |
tags | draft, paused |
status | Follows status flow |
Valid Status Transitions
| From | To |
|---|---|
draft | pending_review |
pending_review | active, rejected (system only) |
active | paused, delisted |
paused | active, delisted |
Response
{
"success": true,
"data": {
"listing_id": "listing_abc123",
"status": "pending_review",
"updated_fields": ["title", "status"],
"message": "Listing submitted for review. It will be published once approved."
}
}Purchase Listing
/api/v1/marketplace/wallet/listings/:id/purchasePurchase access to a listing. Deducts PRIV from buyer and credits seller.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Listing UUID to purchase |
Request Body (Optional)
{
"access_duration_days": 30
}Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
access_duration_days | number | No | Access duration (default: 30, max: 365) |
Response
{
"success": true,
"data": {
"purchase_id": "purchase_xyz789",
"listing_id": "listing_abc123",
"access_token": "at_abc123def456...",
"amount_paid_priv": 25.00,
"expires_at": "2024-02-15T10:30:00Z",
"download_count": 0,
"max_downloads": 10,
"message": "Purchase successful. Use the access token to download the data."
}
}Response Fields
| Field | Type | Description |
|---|---|---|
purchase_id | string | Unique purchase identifier |
access_token | string | Token required for downloads |
amount_paid_priv | number | PRIV amount paid |
expires_at | string | Access expiration timestamp |
download_count | number | Current download count |
max_downloads | number | Maximum allowed downloads |
A 5% platform fee is deducted from the sale price. Sellers receive 95% of the listing price.
Example
curl -X POST "https://api.priv.io/v1/marketplace/wallet/listings/listing_abc123/purchase" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"access_duration_days": 60}'List Purchases
/api/v1/marketplace/wallet/purchasesList your purchases as a buyer.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number (default: 1) |
limit | number | No | Results per page (default: 20, max: 100) |
Response
{
"success": true,
"data": {
"purchases": [
{
"id": "purchase_xyz789",
"listing_id": "listing_abc123",
"listing_title": "Nature Photography Collection",
"listing_category": "photo",
"seller_display_name": "DataProvider_a7x2",
"amount_paid_priv": 25.00,
"access_token": "at_abc123...",
"purchased_at": "2024-01-15T10:30:00Z",
"expires_at": "2024-02-15T10:30:00Z",
"download_count": 2,
"max_downloads": 10,
"status": "active"
}
],
"pagination": {
"total": 5,
"page": 1,
"limit": 20,
"total_pages": 1
}
}
}Purchase Status
| Status | Description |
|---|---|
active | Access is valid |
expired | Access has expired |
revoked | Access was revoked (refund, etc.) |
Download Purchase
/api/v1/marketplace/wallet/purchases/:id/downloadGet download URLs for a purchased listing.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Purchase UUID |
Query Parameters / Headers
Provide the access token via query parameter or header:
| Method | Parameter |
|---|---|
| Query | ?access_token=at_abc123... |
| Header | X-Access-Token: at_abc123... |
Response
{
"success": true,
"data": {
"purchase_id": "purchase_xyz789",
"listing_id": "listing_abc123",
"download_count": 3,
"max_downloads": 10,
"downloads": [
{
"contribution_id": "contrib_abc123",
"contribution_type": "photo",
"filename": "nature_001.jpg",
"file_size_bytes": 2500000,
"mime_type": "image/jpeg",
"gateway_url": "https://gateway.pinata.cloud/ipfs/QmXyz...",
"cid": "QmXyz..."
},
{
"contribution_id": "contrib_def456",
"contribution_type": "photo",
"filename": "nature_002.jpg",
"file_size_bytes": 3200000,
"mime_type": "image/jpeg",
"gateway_url": "https://gateway.pinata.cloud/ipfs/QmAbc...",
"cid": "QmAbc..."
}
],
"expires_at": "2024-02-15T10:30:00Z",
"message": "Download 3 of 10. Access expires 2024-02-15T10:30:00.000Z."
}
}Each call to this endpoint increments the download count. Downloads are limited to prevent abuse.
Example
curl "https://api.priv.io/v1/marketplace/wallet/purchases/purchase_xyz789/download?access_token=at_abc123..." \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."JavaScript Examples
Complete Purchase Flow
// Browse listings
async function browseListings(filters = {}) {
const params = new URLSearchParams(filters);
const response = await fetch(
`https://api.priv.io/v1/marketplace/wallet/listings?${params}`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
return response.json();
}
// Purchase a listing
async function purchaseListing(listingId: string) {
const response = await fetch(
`https://api.priv.io/v1/marketplace/wallet/listings/${listingId}/purchase`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ access_duration_days: 30 }),
}
);
const data = await response.json();
if (!data.success) {
throw new Error(data.error.message);
}
return {
purchaseId: data.data.purchase_id,
accessToken: data.data.access_token,
expiresAt: data.data.expires_at,
};
}
// Download purchased data
async function downloadPurchase(purchaseId: string, accessToken: string) {
const response = await fetch(
`https://api.priv.io/v1/marketplace/wallet/purchases/${purchaseId}/download`,
{
headers: {
'Authorization': `Bearer ${token}`,
'X-Access-Token': accessToken,
},
}
);
const data = await response.json();
// Download each file
for (const file of data.data.downloads) {
console.log(`Downloading: ${file.filename}`);
const fileResponse = await fetch(file.gateway_url);
const blob = await fileResponse.blob();
// Save blob to file system or process as needed
}
return data.data;
}Create and Publish Listing
async function createAndPublishListing(
contributions: string[],
title: string,
description: string,
price: number
) {
// Create draft listing
const createResponse = await fetch(
'https://api.priv.io/v1/marketplace/wallet/listings',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title,
description,
category: 'photo',
price_priv: price,
contribution_ids: contributions,
}),
}
);
const createData = await createResponse.json();
const listingId = createData.data.listing_id;
// Submit for review
const publishResponse = await fetch(
`https://api.priv.io/v1/marketplace/wallet/listings/${listingId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
status: 'pending_review',
}),
}
);
return publishResponse.json();
}