Get Collections
Discover available topics and collections for your contract
GET /v1/collections/<contract-name>The Crowdynews API provides programmatic access to content aggregation and publishing features. This documentation covers all available endpoints for discovering collections, retrieving published content, and monitoring content counts.
Discover Collections
Get a list of available topics for your contract to understand what content is available.
Check Content Count
Use the count endpoint to see how much content is available or check for new content since your last fetch.
Fetch Content
Retrieve the actual content items with filtering and pagination options.
All API requests are made to:
https://q.crowdynews.com/v1/Get Collections
Discover available topics and collections for your contract
GET /v1/collections/<contract-name>Get Content Count
Check how many content items are available or new since last fetch
GET /v1/count/<contract-name>Get Published Content
Retrieve actual content items with filtering and pagination
GET /v1/content/<contract-name>Get a list of available collections/topics for a specific contract. Use this endpoint to discover what content topics are available for your contract.
GET https://q.crowdynews.com/v1/collections/<contract-name>| Parameter | Type | Description |
|---|---|---|
contract-name | String | Required: The slugified name of your contract |
[ { "name": "Premier League", "type": "breakingburner", "url": "https://q.crowdynews.com/v1/content/betway?q=premier-league" }, { "name": "Chelsea FC", "type": "breakingburner", "url": "https://q.crowdynews.com/v1/content/betway?q=chelsea-fc" }]| Property | Type | Description |
|---|---|---|
name | String | Display name of the collection/topic |
type | String | Type of the collection |
url | String | Complete URL to fetch content for this collection |
// Get available collectionsconst response = await fetch('https://q.crowdynews.com/v1/collections/betway');const collections = await response.json();
console.log('Available topics:', collections.map(c => c.name));// Output: ['Premier League', 'Chelsea FC']Get the number of published content items for a specific collection. This endpoint is essential for efficient content management - use it to check for new content before fetching full data.
GET https://q.crowdynews.com/v1/count/<contract-name>| Parameter | Type | Description |
|---|---|---|
contract-name | String | Required: The slugified name of your contract |
| Parameter | Type | Description |
|---|---|---|
q | String | Required: The slugified topic name (from collections API) |
service | String | Optional: Filter by service (twitter, youtube, instagram, rss) |
since | Integer | Optional: Unix timestamp - show content after this time |
until | Integer | Optional: Unix timestamp - show content until this time |
type | String | Optional: Filter by content type (image, video, status, link, embed) |
{ "count": "256" }{ "requestId": "075105a6-4ee6-4fa2-8e90-637739b6f388", "errors": [ { "name": "NotFoundError", "message": "Unknown topic or collectionId" } ] }// Store the timestamp of your last content fetchconst lastFetchTime = Math.floor(Date.now() / 1000) - 3600; // 1 hour ago
// Check how many new items are availableconst countResponse = await fetch( `https://q.crowdynews.com/v1/count/betway?q=premier-league&since=${lastFetchTime}`);const result = await countResponse.json();
if (parseInt(result.count) > 0) { console.log(`${result.count} new items available since last fetch`); // Now fetch the actual content using the content API with the same 'since' parameter fetchNewContent(lastFetchTime);} else { console.log('No new content available');}Retrieve published content items for a specific topic. This is the main endpoint for getting actual content data.
GET https://q.crowdynews.com/v1/content/<contract-name>| Parameter | Type | Description |
|---|---|---|
contract-name | String | Required: The slugified name of your contract |
| Parameter | Type | Description |
|---|---|---|
q | String | Required: The slugified topic name (from collections API) |
service | String | Optional: Filter by service (twitter, youtube, instagram, rss) |
since | Integer | Optional: Unix timestamp - content published after this time |
until | Integer | Optional: Unix timestamp - content published until this time |
count | Integer | Optional: Number of results (1-100, default: 20) |
offset | Integer | Optional: Pagination offset (default: 0) |
order | String | Optional: Sort order (asc, desc, default: desc) |
type | String | Optional: Filter by content type (image, video, status, link, embed) |
[ { "id": "6fc9c511ab95bbd83f8478437a2f87ff1fc4f365", "service": "rss", "type": "link", "title": "Premier League fixture rescheduled", "text": "Our forthcoming Premier League fixture against Burnley has been rescheduled", "url": "https://www.arsenal.com/news/premier-league-fixture-rescheduled-0", "date": "2022-01-09T17:10:00.000Z", "author": { "name": "arsenal", "username": "arsenal" }, "media": [ { "type": "image", "url": "https://www.arsenal.com/sites/default/files/styles/desktop_16x9/public/images/DSC_2115_2021050642150098.JPG?itok=-0Af-IiL" } ], "kudos": { "score": 0, "rss_score": 0 }, "language": "en" }]{ "requestId": "075105a6-4ee6-4fa2-8e90-637739b6f388", "errors": [ { "name": "NotFoundError", "message": "Unknown topic or collectionId" } ] }| Property | Type | Description |
|---|---|---|
id | String | Unique identifier for the content item |
service | String | Source platform (twitter, youtube, instagram, rss) |
type | String | Content type (video, image, link, status, embed, comment) |
title | String | Content title (may not be available for all content types) |
text | String | Content text/description (may contain HTML) |
tags | Array | Array of content tags |
url | String | URL to original content on source platform |
date | DateTime | Publication date in ISO 8601 format |
author | Object | Author information with name and username |
media | Array | Attached media (images, videos, embeds) |
location | Object | Geographic location data (if available) |
kudos | Object | Engagement metrics (likes, shares, etc.) |
language | String | Content language (ISO 639-1 code) |
state | String | Publication state (published, unpublished) |
children | Array | Related content items (comments, replies, etc.) |
Here’s a complete example showing the recommended workflow for efficiently working with the Crowdynews API:
Discover Available Topics
// Get all available collections for your contractconst collectionsResponse = await fetch('https://q.crowdynews.com/v1/collections/your-contract');const collections = await collectionsResponse.json();
console.log('Available topics:');collections.forEach(collection => { console.log(`- ${collection.name}`);});Check for New Content (Efficient)
// Check if there's new content since your last fetchconst lastFetchTime = getLastFetchTimestamp(); // Your stored timestampconst topic = 'premier-league'; // Choose your topic
const countResponse = await fetch( `https://q.crowdynews.com/v1/count/your-contract?q=${topic}&since=${lastFetchTime}`);const countResult = await countResponse.json();
if (parseInt(countResult.count) > 0) { console.log(`${countResult.count} new items available`); // Proceed to fetch content}Fetch New Content
// Fetch only new content using the same 'since' parameterconst contentResponse = await fetch( `https://q.crowdynews.com/v1/content/your-contract?q=${topic}&since=${lastFetchTime}&count=50`);const newContent = await contentResponse.json();
// Process your contentnewContent.forEach(item => { console.log(`New ${item.service} ${item.type}: ${item.title}`);});
// Update your last fetch timestampsaveLastFetchTimestamp(Math.floor(Date.now() / 1000));For large result sets, use pagination:
async function fetchAllContent(contractName, topic, since = null) { let allContent = []; let offset = 0; const limit = 100; // Maximum per request
while (true) { let url = `https://q.crowdynews.com/v1/content/${contractName}?q=${topic}&count=${limit}&offset=${offset}`; if (since) url += `&since=${since}`;
const response = await fetch(url); const content = await response.json();
if (content.length === 0) break; // No more content
allContent.push(...content); offset += limit;
// Break if we got less than the limit (last page) if (content.length < limit) break; }
return allContent;}Error Response Format
All error responses include a requestId and an errors array with detailed error information.
{ "requestId": "request-uuid", "errors": [ { "name": "ErrorType", "message": "Error description", "propertyName": "field_name", "propertyValue": "field_value", "reason": "Additional details", "code": 1001 } ] }Common Errors
async function fetchContentSafely(contractName, topic) { try { const response = await fetch(`https://q.crowdynews.com/v1/content/${contractName}?q=${topic}`);
if (!response.ok) { const errorData = await response.json(); console.error('API Error:', errorData.errors[0].message); return null; }
return await response.json(); } catch (error) { console.error('Network Error:', error.message); return null; }}Brand Toolkit
YouTube
Developer Guidelines
Brand Resources
When displaying content, ensure:
since parameters to fetch only new contentcount values (100) to minimize request numbers