News Articles API
Overviewβ
The News Articles API provides comprehensive access to Ring Platform's news and content management system. This endpoint supports advanced filtering, pagination, search capabilities, and content creation for administrators.
Endpoint Detailsβ
- URL:
/api/news
- Methods:
GET
,POST
- Authentication: GET (Optional), POST (Required - Admin only)
- Rate Limit: 120 requests per minute for GET, 30 for POST
Ring Platform News Systemβ
Content Strategyβ
Ring Platform's news system is designed for professional networking and industry insights:
Content Categoriesβ
- Product Updates: Platform feature announcements
- Industry News: Technology and business insights
- Company Spotlights: Entity and member highlights
- Event Coverage: Conference and meetup reports
- Technical Articles: Development and engineering content
Visibility & Access Controlβ
- Public: Open access articles for general audience
- Member: Exclusive content for verified members
- Confidential: Premium insights for confidential-tier users
Content Management Featuresβ
- SEO Optimization: Meta titles, descriptions, keywords
- Rich Media: Featured images and gallery support
- Social Integration: Sharing and engagement features
- Analytics: View counts and engagement metrics
GET - List News Articlesβ
Query Parametersβ
Parameter | Type | Description | Default |
---|---|---|---|
category | string | Filter by news category | - |
status | string | Filter by status (draft, published, archived) | published |
visibility | string | Filter by visibility (public, member, confidential) | - |
featured | boolean | Filter featured articles only | - |
authorId | string | Filter by author ID | - |
search | string | Search in title, excerpt, content, tags | - |
tags | string | Comma-separated list of tags | - |
limit | number | Number of articles per page | 10 |
offset | number | Number of articles to skip | 0 |
sortBy | string | Sort field (publishedAt, title, views) | publishedAt |
sortOrder | string | Sort direction (asc, desc) | desc |
Request Formatβ
GET /api/news?category=product-updates&limit=20&featured=true
Response Formatβ
Success Response (200 OK)β
{
"success": true,
"data": [
{
"id": "news_123456789",
"title": "Ring Platform Launches Advanced Entity Management",
"slug": "ring-platform-launches-advanced-entity-management",
"excerpt": "Discover the new features that make managing your organization profile easier than ever",
"content": "We're excited to announce the launch of our enhanced entity management system...",
"authorId": "user_987654321",
"authorName": "Ring Platform Team",
"category": "product-updates",
"tags": ["platform", "entities", "features", "management"],
"featuredImage": "https://storage.ring.ck.ua/news/entity-management-hero.jpg",
"gallery": [
"https://storage.ring.ck.ua/news/gallery/screenshot1.jpg",
"https://storage.ring.ck.ua/news/gallery/screenshot2.jpg"
],
"status": "published",
"visibility": "public",
"featured": true,
"views": 1247,
"likes": 89,
"comments": 23,
"publishedAt": "2025-01-14T10:00:00Z",
"createdAt": "2025-01-14T09:30:00Z",
"updatedAt": "2025-01-14T17:20:00Z",
"seo": {
"metaTitle": "Ring Platform Launches Advanced Entity Management",
"metaDescription": "Discover the new features that make managing your organization profile easier than ever",
"keywords": ["ring platform", "entity management", "features"]
}
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 1
},
"filters": {
"category": "product-updates",
"status": "published",
"featured": true,
"limit": 20,
"offset": 0,
"sortBy": "publishedAt",
"sortOrder": "desc"
}
}
Code Examplesβ
JavaScript/TypeScriptβ
interface NewsArticle {
id: string;
title: string;
slug: string;
excerpt: string;
content: string;
authorId: string;
authorName: string;
category: string;
tags: string[];
featuredImage?: string;
gallery: string[];
status: 'draft' | 'published' | 'archived';
visibility: 'public' | 'member' | 'confidential';
featured: boolean;
views: number;
likes: number;
comments: number;
publishedAt: string;
createdAt: string;
updatedAt: string;
seo?: {
metaTitle: string;
metaDescription: string;
keywords: string[];
};
}
interface NewsFilters {
category?: string;
status?: 'draft' | 'published' | 'archived';
visibility?: 'public' | 'member' | 'confidential';
featured?: boolean;
authorId?: string;
search?: string;
tags?: string[];
limit?: number;
offset?: number;
sortBy?: 'publishedAt' | 'title' | 'views';
sortOrder?: 'asc' | 'desc';
}
async function getNewsArticles(filters: NewsFilters = {}): Promise<{
data: NewsArticle[];
pagination: { limit: number; offset: number; total: number };
filters: NewsFilters;
}> {
const params = new URLSearchParams();
Object.entries(filters).forEach(([key, value]) => {
if (value !== undefined) {
if (Array.isArray(value)) {
params.append(key, value.join(','));
} else {
params.append(key, String(value));
}
}
});
const response = await fetch(`/api/news?${params.toString()}`);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Failed to fetch news articles');
}
return response.json();
}
// Usage examples
try {
// Get featured articles
const featured = await getNewsArticles({ featured: true, limit: 5 });
// Search articles
const searchResults = await getNewsArticles({
search: 'blockchain',
category: 'technology'
});
// Get articles by tags
const taggedArticles = await getNewsArticles({
tags: ['platform', 'features'],
sortBy: 'views',
sortOrder: 'desc'
});
console.log('Featured articles:', featured.data.length);
} catch (error) {
console.error('Error:', error.message);
}
React Hook Exampleβ
import { useState, useEffect } from 'react';
interface UseNewsArticlesResult {
articles: NewsArticle[];
loading: boolean;
error: string | null;
pagination: { limit: number; offset: number; total: number };
loadMore: () => void;
refresh: () => void;
}
function useNewsArticles(filters: NewsFilters = {}): UseNewsArticlesResult {
const [articles, setArticles] = useState<NewsArticle[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [pagination, setPagination] = useState({ limit: 10, offset: 0, total: 0 });
const fetchArticles = async (append = false) => {
try {
setLoading(true);
setError(null);
const currentOffset = append ? articles.length : 0;
const result = await getNewsArticles({
...filters,
offset: currentOffset
});
setArticles(prev => append ? [...prev, ...result.data] : result.data);
setPagination(result.pagination);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchArticles();
}, [JSON.stringify(filters)]);
const loadMore = () => {
if (!loading && articles.length < pagination.total) {
fetchArticles(true);
}
};
const refresh = () => {
fetchArticles();
};
return { articles, loading, error, pagination, loadMore, refresh };
}
// Usage in component
function NewsListPage() {
const [filters, setFilters] = useState<NewsFilters>({
status: 'published',
limit: 12
});
const { articles, loading, error, pagination, loadMore } = useNewsArticles(filters);
const handleCategoryFilter = (category: string) => {
setFilters(prev => ({ ...prev, category, offset: 0 }));
};
const handleSearch = (search: string) => {
setFilters(prev => ({ ...prev, search, offset: 0 }));
};
if (loading && articles.length === 0) {
return <div>Loading news articles...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div className="news-list">
<header>
<h1>Ring Platform News</h1>
<div className="filters">
<input
type="text"
placeholder="Search articles..."
onChange={(e) => handleSearch(e.target.value)}
/>
<select onChange={(e) => handleCategoryFilter(e.target.value)}>
<option value="">All Categories</option>
<option value="product-updates">Product Updates</option>
<option value="industry-news">Industry News</option>
<option value="company-spotlights">Company Spotlights</option>
</select>
</div>
</header>
<div className="articles-grid">
{articles.map(article => (
<article key={article.id} className="article-card">
{article.featuredImage && (
<img src={article.featuredImage} alt={article.title} />
)}
<div className="article-content">
<h2>{article.title}</h2>
<p>{article.excerpt}</p>
<div className="article-meta">
<span>By {article.authorName}</span>
<span>{new Date(article.publishedAt).toLocaleDateString()}</span>
<span>{article.views} views</span>
</div>
<div className="article-tags">
{article.tags.map(tag => (
<span key={tag} className="tag">#{tag}</span>
))}
</div>
</div>
</article>
))}
</div>
{articles.length < pagination.total && (
<button onClick={loadMore} disabled={loading}>
{loading ? 'Loading...' : 'Load More'}
</button>
)}
</div>
);
}
cURL Examplesβ
# Get all published articles
curl "https://ring.ck.ua/api/news?status=published&limit=10"
# Get featured articles
curl "https://ring.ck.ua/api/news?featured=true"
# Search articles
curl "https://ring.ck.ua/api/news?search=blockchain&category=technology"
# Get articles by tags
curl "https://ring.ck.ua/api/news?tags=platform,features&sortBy=views&sortOrder=desc"
# Get articles with pagination
curl "https://ring.ck.ua/api/news?limit=20&offset=40"
POST - Create News Articleβ
Authentication Requirementsβ
- ADMIN Role: Only administrators can create news articles
Request Formatβ
POST /api/news
Content-Type: application/json
Authorization: Bearer <admin_jwt_token>
Request Body Schemaβ
interface CreateNewsRequest {
title: string; // Required: 1-200 characters
content: string; // Required: Article content
excerpt: string; // Required: 1-500 characters
slug?: string; // Optional: Auto-generated if not provided
category?: string; // Optional: Default 'other'
tags?: string[]; // Optional: Max 10 tags
featuredImage?: string; // Optional: Image URL
gallery?: string[]; // Optional: Gallery image URLs
status?: 'draft' | 'published'; // Optional: Default 'draft'
visibility?: 'public' | 'member' | 'confidential'; // Optional: Default 'public'
featured?: boolean; // Optional: Default false
seo?: {
metaTitle?: string;
metaDescription?: string;
keywords?: string[];
};
}
Example Request Bodyβ
{
"title": "Ring Platform Introduces Advanced Analytics Dashboard",
"content": "We're excited to announce the launch of our new analytics dashboard that provides comprehensive insights into your professional network performance...",
"excerpt": "Discover powerful analytics tools to track your networking success and optimize your professional connections",
"category": "product-updates",
"tags": ["analytics", "dashboard", "insights", "networking"],
"featuredImage": "https://storage.ring.ck.ua/news/analytics-dashboard.jpg",
"status": "published",
"visibility": "public",
"featured": true,
"seo": {
"metaTitle": "Ring Platform Introduces Advanced Analytics Dashboard",
"metaDescription": "Discover powerful analytics tools to track your networking success",
"keywords": ["analytics", "dashboard", "networking", "insights"]
}
}
Response Formatβ
Success Response (200 OK)β
{
"success": true,
"data": {
"id": "news_987654321",
"title": "Ring Platform Introduces Advanced Analytics Dashboard",
"slug": "ring-platform-introduces-advanced-analytics-dashboard",
"content": "We're excited to announce the launch of our new analytics dashboard...",
"excerpt": "Discover powerful analytics tools to track your networking success",
"authorId": "admin_123456789",
"authorName": "Admin User",
"category": "product-updates",
"tags": ["analytics", "dashboard", "insights", "networking"],
"featuredImage": "https://storage.ring.ck.ua/news/analytics-dashboard.jpg",
"status": "published",
"visibility": "public",
"featured": true,
"views": 0,
"likes": 0,
"comments": 0,
"publishedAt": "2025-01-14T18:00:00Z",
"createdAt": "2025-01-14T18:00:00Z",
"updatedAt": "2025-01-14T18:00:00Z",
"seo": {
"metaTitle": "Ring Platform Introduces Advanced Analytics Dashboard",
"metaDescription": "Discover powerful analytics tools to track your networking success",
"keywords": ["analytics", "dashboard", "networking", "insights"]
}
},
"message": "News article created successfully"
}
Error Responsesβ
// 401 Unauthorized
{
"success": false,
"error": "Authentication required"
}
// 403 Forbidden
{
"success": false,
"error": "Admin access required"
}
// 400 Bad Request - Missing required fields
{
"success": false,
"error": "Title, content, and excerpt are required"
}
// 400 Bad Request - Duplicate slug
{
"success": false,
"error": "Article with this slug already exists"
}