Skip to content

entries.list()

List entries from a specific feed with optional pagination.

Signature

entries.list(feedId: string, query?: ListEntriesQuery): Promise<PaginatedResponse<Entry>>

Parameters

feedId

  • Type: string
  • Required: Yes
  • Description: The UUID of the feed to list entries from

query

  • Type: ListEntriesQuery (optional)
interface ListEntriesQuery {
  page_size?: number;        // Max results per page (default: 20)
  page_token?: string;       // Pagination token from previous response
  is_free?: boolean;         // Filter free/paid entries
}

Returns

  • Type: Promise<PaginatedResponse<Entry>>
interface PaginatedResponse<Entry> {
  data: Entry[];                    // Array of entries
  next_page_token?: string;         // Token for next page (if more results)
  has_more: boolean;                // Whether more results exist
}
 
interface Entry {
  id: string;
  feed_id: string;
  cid: string;                      // Content identifier
  mime_type: string;
  title?: string;
  description?: string;
  metadata?: string;                // JSON string of additional metadata
  tags: string[];
  is_free: boolean;
  expires_at?: number;              // Unix timestamp expiration
  is_active: boolean;
  total_purchases: number;
  total_revenue: string;            // Revenue in wei
  created_at: number;
  updated_at: number;
}

Usage

Basic Example

// List all entries from a feed
const response = await grapevine.entries.list(feedId);
 
console.log(`Found ${response.data.length} entries (has more: ${response.has_more})`);
response.data.forEach(entry => {
  console.log(`- ${entry.title || 'Untitled'}: ${entry.is_free ? 'Free' : 'Paid'}`);
  console.log(`  Content ID: ${entry.cid}`);
});

Filter Free Entries

// Get only free entries
const freeEntries = await grapevine.entries.list(feedId, {
  is_free: true
});
 
console.log(`${freeEntries.data.length} free entries available`);

With Pagination

// Get entries with custom page size
const entries = await grapevine.entries.list(feedId, {
  page_size: 50,
  is_free: true
});

Pagination

// Paginate through all entries
async function getAllEntries(feedId: string) {
  const allEntries: Entry[] = [];
  let pageToken: string | undefined;
  
  do {
    const response = await grapevine.entries.list(feedId, {
      page_size: 100,
      page_token: pageToken
    });
    
    allEntries.push(...response.data);
    pageToken = response.next_page_token;
  } while (pageToken);
  
  return allEntries;
}

Latest Entries

// Get latest 5 entries
const latest = await grapevine.entries.list(feedId, {
  page_size: 5
});
 
latest.data.forEach(entry => {
  const date = new Date(entry.created_at * 1000);
  console.log(`${entry.title} - ${date.toLocaleDateString()}`);
});

Content Access

To access entry content, you need to use the entry's cid (Content Identifier) after purchasing or if the entry is free:

// List entries and check access
const entries = await grapevine.entries.list(feedId);
 
entries.data.forEach(entry => {
  console.log(`Entry: ${entry.title || 'Untitled'}`);
  console.log(`  CID: ${entry.cid}`);
  console.log(`  Type: ${entry.is_free ? 'Free' : 'Paid'}`);
  console.log(`  MIME: ${entry.mime_type}`);
  
  // Content is accessed via IPFS using the CID
  // For free entries or purchased entries, use the access link endpoint
});
 
// To get content for a specific entry, create an access link:
const accessLink = await grapevine.feeds.createAccessLink(feedId, entryId);
console.log('Access URL:', accessLink.url);
console.log('Expires at:', new Date(accessLink.expires_at * 1000));

Behind the Scenes

This method:

  1. Validates feed ID format
  2. Builds query parameters from options
  3. Makes GET request to /v1/feeds/{feedId}/entries
  4. Returns entries with content based on access rights
  5. Free entries always include content
  6. Paid entries include content only if you own or purchased them

Error Handling

try {
  const entries = await grapevine.entries.list(feedId);
  console.log(`Found ${entries.data.length} entries`);
} catch (error) {
  if (error.message.includes('404')) {
    console.error('Feed not found');
  } else if (error.message.includes('400')) {
    console.error('Invalid parameters');
  } else {
    console.error('Error:', error.message);
  }
}

Notes

  • Authentication: Optional - affects content visibility
  • Content Access: Free entries visible to all, paid require purchase
  • Default Sort: By creation date, newest first
  • Maximum Limit: 100 entries per request
  • Content Format: Based on mime_type field

Related