Documentation Index
Fetch the complete documentation index at: https://docs.suprsonic.com/llms.txt
Use this file to discover all available pages before exploring further.
The SuprSonic API uses cursor-based pagination with HATEOAS links to help you efficiently navigate through large datasets. All list endpoints support pagination with consistent parameters and response formats.
| Parameter | Type | Default | Description |
|---|
page | integer | 1 | Page number (1-based) |
limit | integer | 20 | Items per page (1-100) |
Example Request
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.suprsonic.com/api/v1/articles?page=2&limit=10"
All paginated responses include metadata and navigation links:
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Article Title",
// ... article data
}
],
"meta": {
"pagination": {
"page": 2,
"limit": 10,
"total": 145,
"totalPages": 15,
"hasNext": true,
"hasPrev": true
},
"links": {
"self": "/api/v1/articles?page=2&limit=10",
"first": "/api/v1/articles?page=1&limit=10",
"prev": "/api/v1/articles?page=1&limit=10",
"next": "/api/v1/articles?page=3&limit=10",
"last": "/api/v1/articles?page=15&limit=10"
}
}
}
| Field | Type | Description |
|---|
page | integer | Current page number |
limit | integer | Items per page |
total | integer | Total number of items |
totalPages | integer | Total number of pages |
hasNext | boolean | Whether there’s a next page |
hasPrev | boolean | Whether there’s a previous page |
HATEOAS Links
Navigation links preserve all query parameters from your original request:
| Link | Description |
|---|
self | Current page |
first | First page |
prev | Previous page (if exists) |
next | Next page (if exists) |
last | Last page |
When using filters, pagination links automatically preserve your search parameters:
# Request with filters
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.suprsonic.com/api/v1/articles?q=SEO&tags=marketing&status=published&page=1&limit=10"
{
"success": true,
"data": [...],
"meta": {
"pagination": {...},
"links": {
"self": "/api/v1/articles?q=SEO&tags=marketing&status=published&page=1&limit=10",
"next": "/api/v1/articles?q=SEO&tags=marketing&status=published&page=2&limit=10"
}
}
}
Implementation Examples
JavaScript/Node.js
class SuprSonicClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://www.suprsonic.com/api/v1';
}
async getAllArticles(filters = {}) {
let allArticles = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await this.getArticles({
...filters,
page,
limit: 100
});
allArticles.push(...response.data);
hasMore = response.meta.pagination.hasNext;
page++;
}
return allArticles;
}
async getArticles(params = {}) {
const queryString = new URLSearchParams(params).toString();
const url = `${this.baseUrl}/articles?${queryString}`;
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${this.apiKey}` }
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return await response.json();
}
// Iterator pattern for memory efficiency
async* iterateArticles(filters = {}) {
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await this.getArticles({
...filters,
page,
limit: 50
});
for (const article of response.data) {
yield article;
}
hasMore = response.meta.pagination.hasNext;
page++;
}
}
}
// Usage examples
const client = new SuprSonicClient('your-api-key');
// Get all articles (automatic pagination)
const allArticles = await client.getAllArticles({
status: 'published'
});
// Process articles one at a time (memory efficient)
for await (const article of client.iterateArticles({ q: 'SEO' })) {
console.log(`Processing: ${article.title}`);
}
// Manual pagination with HATEOAS links
let response = await client.getArticles({ limit: 20 });
while (response.meta.pagination.hasNext) {
// Process current page
console.log(`Page ${response.meta.pagination.page}: ${response.data.length} articles`);
// Use HATEOAS link for next page
const nextUrl = response.meta.links.next;
const nextResponse = await fetch(`https://www.suprsonic.com${nextUrl}`, {
headers: { 'Authorization': `Bearer ${client.apiKey}` }
});
response = await nextResponse.json();
}
Python
import requests
from typing import Generator, Dict, Any, Optional
class SuprSonicClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://www.suprsonic.com/api/v1"
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}"
})
def get_articles(self, **params) -> Dict[str, Any]:
"""Get a single page of articles."""
response = self.session.get(f"{self.base_url}/articles", params=params)
response.raise_for_status()
return response.json()
def iterate_all_articles(self, **filters) -> Generator[Dict[str, Any], None, None]:
"""Iterate through all articles across all pages."""
page = 1
while True:
response = self.get_articles(page=page, limit=100, **filters)
for article in response["data"]:
yield article
if not response["meta"]["pagination"]["hasNext"]:
break
page += 1
def get_all_articles(self, **filters) -> list[Dict[str, Any]]:
"""Get all articles as a list."""
return list(self.iterate_all_articles(**filters))
# Usage
client = SuprSonicClient("your-api-key")
# Process articles one by one (memory efficient)
for article in client.iterate_all_articles(status="published"):
print(f"Processing: {article['title']}")
# Get all articles at once
all_articles = client.get_all_articles(tags="seo,marketing")
print(f"Found {len(all_articles)} articles")
# Manual pagination
response = client.get_articles(limit=20)
print(f"Page {response['meta']['pagination']['page']} of {response['meta']['pagination']['totalPages']}")
Best Practices
1. Use Appropriate Page Sizes
// Good: Reasonable page sizes
const response = await getArticles({ limit: 20 }); // UI pagination
const response = await getArticles({ limit: 100 }); // Bulk processing
// Avoid: Too small (many requests)
const response = await getArticles({ limit: 5 });
// Avoid: Too large (slow responses)
const response = await getArticles({ limit: 1000 });
2. Handle Pagination Errors
async function safePagination(client, filters) {
const results = [];
let page = 1;
const maxRetries = 3;
while (true) {
try {
const response = await client.getArticles({
...filters,
page,
limit: 50
});
results.push(...response.data);
if (!response.meta.pagination.hasNext) break;
page++;
} catch (error) {
if (error.status === 429) {
// Rate limited - wait and retry
await new Promise(resolve => setTimeout(resolve, 1000));
continue;
}
throw error;
}
}
return results;
}
3. Cache and Store Results
class CachedSuprSonicClient {
constructor(apiKey, cacheSize = 1000) {
this.client = new SuprSonicClient(apiKey);
this.cache = new Map();
this.cacheSize = cacheSize;
}
async getArticles(params = {}) {
const cacheKey = JSON.stringify(params);
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
const response = await this.client.getArticles(params);
// Simple LRU cache
if (this.cache.size >= this.cacheSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(cacheKey, response);
return response;
}
}
Performance Considerations
- Optimize page size: Balance between request frequency and response time
- Use filters: Reduce total items to paginate through
- Implement caching: Cache responses for frequently accessed pages
- Monitor rate limits: Implement exponential backoff for rate-limited requests
- Stream processing: Use iterators for large datasets to avoid memory issues
Common Patterns
# Search articles and paginate results
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.suprsonic.com/api/v1/articles?q=content+marketing&page=1&limit=25"
Filter by Multiple Tags
# Get articles with specific tags
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.suprsonic.com/api/v1/articles?tags=seo,marketing,content&page=1&limit=50"
# Paginate through draft articles
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://www.suprsonic.com/api/v1/articles?status=draft&page=1&limit=10"