Artist Platform REST API Integration
The artist platform exposes comprehensive REST API endpoints through the extrachill-api plugin, enabling mobile apps, third-party integrations, and external tools to access artist data.
REST API Base
All artist platform endpoints are available under:
/wp-json/extrachill/v1/artist/
Available Endpoints
Artist Profiles
Get Single Artist
GET /wp-json/extrachill/v1/artist/{artist_id}
Returns complete artist profile data:
{
"id": 123,
"name": "Extra Chill",
"slug": "extra-chill",
"description": "Independent music journalism",
"image": "https://artist.extrachill.com/wp-content/uploads/artist-image.jpg",
"genres": ["indie", "hip-hop"],
"social_links": {
"spotify": "https://spotify.com/artist/...",
"twitter": "@extrachill",
"instagram": "@extrachill"
},
"subscriber_count": 1250,
"link_page_url": "https://extrachill.link/extra-chill"
}
List Artists
GET /wp-json/extrachill/v1/artist?page=1&per_page=20&search=extra
Parameters:
page(int) – Page number (default: 1)per_page(int) – Items per page (default: 20, max: 100)search(string) – Search artist name/descriptiongenre(string) – Filter by genre slugorderby(string) –name,created,subscribers(default:name)order(string) –ascordesc
Link Pages
Get Link Page Data
GET /wp-json/extrachill/v1/artist/{artist_id}/link-page
Returns link page configuration and current data:
{
"id": 456,
"artist_id": 123,
"title": "Extra Chill Links",
"url": "https://extrachill.link/extra-chill",
"links": [
{
"id": "spotify",
"title": "Spotify",
"url": "https://spotify.com/artist/...",
"clicks": 342
}
],
"appearance": {
"background_color": "#000000",
"text_color": "#ffffff",
"button_color": "#53940b"
},
"stats": {
"total_views": 12450,
"total_clicks": 3280,
"subscribers": 145
}
}
Subscribers
List Artist Subscribers
GET /wp-json/extrachill/v1/artist/{artist_id}/subscribers?page=1&per_page=50
Requires authentication (artist owner only)
Returns:
{
"total": 145,
"page": 1,
"per_page": 50,
"subscribers": [
{
"id": 789,
"email": "[email protected]",
"subscribed_date": "2024-01-15T10:30:00Z",
"status": "active"
}
]
}
Export Subscribers
POST /wp-json/extrachill/v1/artist/{artist_id}/subscribers/export
Triggers export of all subscribers to CSV, returns download link:
{
"success": true,
"download_url": "https://artist.extrachill.com/wp-content/uploads/exports/subscribers-123.csv",
"expires_in_hours": 24
}
Analytics
Get Link Page Analytics
GET /wp-json/extrachill/v1/artist/{artist_id}/analytics?start_date=2024-01-01&end_date=2024-01-31
Returns analytics data for a date range:
{
"artist_id": 123,
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"summary": {
"total_views": 5420,
"total_clicks": 1280,
"unique_visitors": 3100,
"new_subscribers": 45
},
"daily_breakdown": [
{
"date": "2024-01-01",
"views": 175,
"clicks": 42,
"clicks_by_link": {
"spotify": 28,
"instagram": 14
}
}
]
}
Authentication
Required Authentication
Most endpoints require authentication as the artist owner:
// Include WordPress authentication cookie
fetch('/wp-json/extrachill/v1/artist/123', {
credentials: 'include', // Include WordPress session cookie
headers: {
'Content-Type': 'application/json'
}
});
Bearer Access Token (Optional)
For external applications, use a Bearer access token:
const token = '...';
fetch('/wp-json/extrachill/v1/artist/123', {
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
});
Request/Response Examples
Example 1: Get Artist Profile via JavaScript
// Get artist by ID
async function getArtist(artistId) {
const response = await fetch(`/wp-json/extrachill/v1/artist/${artistId}`);
if (!response.ok) {
throw new Error('Failed to fetch artist: ' + response.status);
}
return response.json();
}
// Usage
getArtist(123)
.then(artist => {
console.log('Artist:', artist.name);
console.log('Genre:', artist.genres);
console.log('Subscribers:', artist.subscriber_count);
})
.catch(error => console.error('Error:', error));
Example 2: Search Artists
// Search artists with filters
async function searchArtists(query, genre = null) {
const params = new URLSearchParams({
search: query,
per_page: 20
});
if (genre) {
params.append('genre', genre);
}
const response = await fetch(`/wp-json/extrachill/v1/artist?${params}`);
return response.json();
}
// Usage
searchArtists('indie', 'indie-rock')
.then(results => {
results.forEach(artist => {
console.log(`${artist.name} - ${artist.genres.join(', ')}`);
});
});
Example 3: Get Link Page Analytics
// Fetch analytics with date range
async function getAnalytics(artistId, startDate, endDate) {
const params = new URLSearchParams({
start_date: startDate,
end_date: endDate
});
const response = await fetch(
`/wp-json/extrachill/v1/artist/${artistId}/analytics?${params}`,
{
credentials: 'include' // Include auth cookie
}
);
if (!response.ok) {
throw new Error('Unauthorized');
}
return response.json();
}
// Usage
const start = '2024-01-01';
const end = '2024-01-31';
getAnalytics(123, start, end)
.then(data => {
console.log('Views:', data.summary.total_views);
console.log('Clicks:', data.summary.total_clicks);
console.log('Daily:', data.daily_breakdown);
});
Error Handling
Common Error Codes
404 Not Found
{
"code": "rest_post_invalid_id",
"message": "Invalid post id.",
"data": {
"status": 404
}
}
401 Unauthorized
{
"code": "rest_forbidden",
"message": "Sorry, you are not allowed to do this.",
"data": {
"status": 401
}
}
400 Bad Request
{
"code": "rest_invalid_param",
"message": "Invalid parameter(s): start_date",
"data": {
"status": 400,
"params": ["start_date"]
}
}
Error Handling Pattern
async function apiCall(endpoint) {
try {
const response = await fetch(endpoint, {
credentials: 'include'
});
if (!response.ok) {
const error = await response.json();
if (response.status === 401) {
console.error('Please log in');
} else if (response.status === 404) {
console.error('Resource not found');
} else {
console.error('Error:', error.message);
}
return null;
}
return response.json();
} catch (error) {
console.error('Network error:', error);
return null;
}
}
Rate Limiting
API endpoints are rate-limited to prevent abuse:
- Authenticated requests: 60 requests per minute
- Unauthenticated requests: 20 requests per minute
- Headers returned:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remaining in current windowX-RateLimit-Reset: Unix timestamp when limit resets
// Check rate limit headers
fetch('/wp-json/extrachill/v1/artist')
.then(response => {
const limit = response.headers.get('X-RateLimit-Limit');
const remaining = response.headers.get('X-RateLimit-Remaining');
console.log(`Requests remaining: ${remaining}/${limit}`);
return response.json();
});
Use Cases
Mobile App Integration
// Fetch artist profile data for mobile app
const artistId = 123;
const artist = await fetch(`/wp-json/extrachill/v1/artist/${artistId}`)
.then(r => r.json());
// Display artist info
console.log(`${artist.name} - ${artist.genres.join(', ')}`);
// Get social links
artist.social_links.forEach(link => {
console.log(`${link.type}: ${link.url}`);
});
// Link to link page
window.location = artist.link_page_url;
Third-Party Dashboard Integration
// Create dashboard widget showing artist stats
async function updateArtistWidget(artistId) {
const data = await fetch(
`/wp-json/extrachill/v1/artist/${artistId}/analytics?days=30`,
{ credentials: 'include' }
).then(r => r.json());
document.querySelector('.widget-views').textContent = data.summary.total_views;
document.querySelector('.widget-clicks').textContent = data.summary.total_clicks;
document.querySelector('.widget-subscribers').textContent = data.summary.new_subscribers;
}
Export Workflow
// Trigger subscriber export
async function exportSubscribers(artistId) {
const response = await fetch(
`/wp-json/extrachill/v1/artist/${artistId}/subscribers/export`,
{
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' }
}
);
const data = await response.json();
if (data.success) {
// Trigger download
const link = document.createElement('a');
link.href = data.download_url;
link.download = 'subscribers.csv';
link.click();
}
}
Related Endpoints
See extrachill-api plugin documentation for:
- All available REST endpoints
- Authentication methods
- Request/response formats
- Error handling patterns
Cross-Reference
- Artist Platform CLAUDE.md – Full plugin architecture
- Link Page System – Link page implementation
- Analytics System – Analytics tracking