Marketplace API Reference
All marketplace operations use POST /api/marketplace with an action field in the JSON body.
Actions
create — List a Note for Sale
Create a new marketplace listing.
Request:
{
"action": "create",
"noteTitle": "My Guide",
"noteContent": "# Full markdown content...",
"description": "A brief description visible to buyers",
"sellerAddress": "...",
"sellerUsername": "Alice",
"listingType": "copy",
"price": 0.5,
"category": "Guide",
"previewMode": "masked",
"previewChars": 200,
"auctionDuration": 24,
"reservePrice": 1.0
}
| Field | Type | Required | Description |
|---|---|---|---|
listingType | string | Yes | "copy", "original", or "auction" |
previewMode | string | No | "masked" (default), "partial", or "full" |
previewChars | number | No | Characters to show in partial mode (50-2000) |
auctionDuration | number | No | Auction duration in hours (auction only) |
reservePrice | number | No | Minimum price to sell (auction only) |
Similarity Check: Before creating, the API compares content against all existing listings from other sellers using trigram-based Jaccard similarity. Listings with 70%+ similarity to existing content are rejected.
Response:
{ "listingId": "abc123..." }
browse — List Marketplace Listings
Fetch all active listings with optional filters. Results are paginated.
Request:
{
"action": "browse",
"category": "Tutorial",
"search": "solana",
"seller": "...",
"page": 1,
"limit": 20
}
All filter fields are optional. Returns public info only (no noteContent).
Response:
{
"listings": [...],
"page": 1,
"limit": 20,
"total": 45
}
get — Get Single Listing
Fetch a listing's details. If the buyer has purchased it, includes the full content.
Request:
{
"action": "get",
"listingId": "abc123...",
"buyerAddress": "..."
}
purchase — Record a Purchase
Called after the on-chain payment is confirmed.
Request:
{
"action": "purchase",
"listingId": "abc123...",
"buyerAddress": "...",
"txSignature": "..."
}
Validations:
- Listing must exist and not be a sold original
- Buyer cannot purchase their own listing
Response:
{
"purchase": { "id": "...", "listingId": "...", "buyerAddress": "...", "txSignature": "...", "purchasedAt": 1712345678000 },
"noteContent": "# Full markdown content",
"noteTitle": "My Guide"
}
bid — Place an Auction Bid
Request:
{
"action": "bid",
"listingId": "abc123...",
"bidderAddress": "...",
"bidderUsername": "Bob",
"amount": 0.75
}
Validations:
- Must be an active auction (not ended, not settled)
- Bid must exceed current highest bid by at least 0.001 SOL
- Cannot bid on your own auction
settle — Settle an Ended Auction
Called by the winning bidder after the auction ends and on-chain payment is confirmed.
Request:
{
"action": "settle",
"listingId": "abc123...",
"buyerAddress": "...",
"txSignature": "..."
}
Validations:
- Auction must have ended
- Caller must be the highest bidder
- Reserve price must be met (if set)
analytics — Transaction Analytics
Returns all purchase transactions and aggregate statistics.
Request:
{ "action": "analytics" }
Response:
{
"transactions": [...],
"stats": {
"totalSales": 15,
"totalVolume": 7.5,
"totalFees": 0.15,
"uniqueBuyers": 8,
"uniqueSellers": 5,
"activeListings": 12
}
}
delete — Delete a Listing
Seller-only. Removes a listing from the marketplace.
Request:
{
"action": "delete",
"listingId": "abc123...",
"sellerAddress": "..."
}
Content Protection
Similarity Detection
When a new listing is created, its content is compared against all existing listings from other sellers:
- Text is normalized (lowercase, markdown syntax stripped, whitespace collapsed)
- Word trigrams are generated from both texts
- Jaccard similarity coefficient is computed:
|A intersection B| / |A union B| - If similarity >= 70%, the listing is rejected
This prevents buyers from reselling purchased content, even if they copy-paste it into a new note with minor edits.
Purchase Tagging
Notes acquired through marketplace purchases are tagged with purchasedFrom (the listing ID). Tagged notes cannot be listed for sale — the sell button is disabled in the UI, and the API rejects the request.
Proof API Reference
Proof operations use POST /api/proof with an action field in the JSON body.
store — Store a Proof Record
Upserts a proof record into the Supabase proofs table after the on-chain register_proof transaction is confirmed.
Request:
{
"action": "store",
"walletAddress": "Ad67Rwg...",
"noteHash": "a1b2c3d4e5f6...",
"title": "My Original Note",
"content": "# Full note content...",
"txSignature": "5KtR9..."
}
verify — Verify a Proof by Hash
Performs an exact hash lookup in the proofs table.
Request:
{
"action": "verify",
"noteHash": "a1b2c3d4e5f6..."
}
Response (found):
{
"found": true,
"proof": {
"walletAddress": "Ad67Rwg...",
"noteHash": "a1b2c3d4e5f6...",
"title": "My Original Note",
"txSignature": "5KtR9...",
"createdAt": "2026-04-01T12:00:00Z"
}
}
search — Similarity Search
Performs a trigram similarity search against stored proof titles and content.
Request:
{
"action": "search",
"query": "solana smart contract guide"
}
Response:
{
"results": [
{
"walletAddress": "Ad67Rwg...",
"noteHash": "a1b2c3d4e5f6...",
"title": "Solana Smart Contract Tutorial",
"txSignature": "5KtR9...",
"similarity": 0.82,
"createdAt": "2026-04-01T12:00:00Z"
}
]
}
Results are ordered by similarity score (highest first). The similarity value ranges from 0.0 to 1.0.