Network-activated REST API infrastructure for the Extra Chill Platform WordPress multisite network. Centralizes all custom REST endpoints under a single extrachill/v1 namespace for consistent access across web, mobile, and AI clients.
The ExtraChill API plugin provides a centralized, versioned REST API infrastructure that replaces legacy admin-ajax.php handlers with modern WordPress REST API endpoints. It uses automatic route discovery to modularly organize endpoints by feature area while maintaining a consistent API surface across the entire multisite network.
- Network-Wide Activation: All endpoints available on every site in the multisite network
- Automatic Route Discovery: Recursively loads route files from
inc/routes/directory - Versioned Namespace: All endpoints under
extrachill/v1for future API evolution - Modular Organization: Routes organized by feature (
blocks/,community/, etc.) - WordPress REST API Standards: Full compliance with WordPress REST API conventions
- Security First: Nonce verification, permission callbacks, input validation on all endpoints
The plugin provides 66 endpoint files across 18 feature categories, all under the extrachill/v1 namespace:
POST /auth/browser-handoff- Browser handoff for cross-device authPOST /auth/google- Google OAuth authenticationPOST /auth/login- User login returning access + refresh tokensPOST /auth/logout- Logout and token revocationGET /auth/me- Get current authenticated userPOST /auth/refresh- Refresh access tokensPOST /auth/register- User registration
GET /config/oauth- OAuth provider configuration
POST /analytics/click- Unified click tracking (shares, link page clicks)POST /analytics/link-page- Track link page views (authenticated)POST /analytics/view- Track content views
GET/PUT /artists/{id}- Core artist profile dataGET/PUT /artists/{id}/socials- Social media linksGET/PUT /artists/{id}/links- Link page dataGET /artists/{id}/analytics- Link page analyticsGET /artists/{id}/permissions- Check artist permissionsGET/POST/DELETE /artists/{id}/roster- Roster member managementGET /artists/{id}/subscribers- List subscribers with paginationGET /artists/{id}/subscribers/export- Export subscribers as CSVPOST /artists/{id}/subscribe- Public subscription signup
POST /blog/band-name- AI band name generationPOST /blog/rapper-name- AI rapper name generationPOST /blog/ai-adventure- AI adventure story generation
GET /blog/image-voting/vote-count/{post_id}/{instance_id}- Get vote countsPOST /blog/image-voting/vote- Cast a vote
POST /chat/message- Send chat message (authenticated)DELETE /chat/history- Clear chat history (authenticated)
GET /users/search- Search users for @mentions and adminPOST /community/upvote- Upvote topics or replies (authenticated)GET/POST/DELETE /community/drafts- Manage bbPress drafts (authenticated)
POST /contact/submit- Submit contact form with Turnstile verification
GET /activity- Activity feed with filtering and pagination (authenticated)GET /object- Object resolver for posts, comments, and artists (authenticated)
GET /admin/artist-access- List pending artist access requestsGET/POST /admin/artist-access/{user_id}/approve- Approve artist access requestPOST /admin/artist-access/{user_id}/reject- Reject artist access requestGET /admin/lifetime-membership- List all lifetime membershipsPOST /admin/lifetime-membership/grant- Grant Lifetime Extra Chill Membership (ad-free)DELETE /admin/lifetime-membership/{user_id}- Revoke Lifetime Extra Chill MembershipGET /admin/team-members- List all team members with search/paginationPOST /admin/team-members/sync- Sync team membersPUT /admin/team-members/{user_id}- Manage team member statusPOST /admin/taxonomies/sync- Sync shared taxonomies across sitesGET /admin/tag-migration- List tags for migration searchingGET /admin/forum-topics- List and manage bbPress topics across networkGET /admin/404-logger- Monitor 404 errors for SEO managementGET /admin/artist-relationships- Manage user-artist links
GET /users/{id}- Get user profileGET/POST /users/onboarding- User onboarding flowGET /users/leaderboard- Get user leaderboard with rankingsGET/POST/DELETE /users/{id}/artists- Manage user-artist relationshipsGET /users/search- Find users (multiple contexts)
GET /docs-info- Documentation metadataPOST /sync/doc- Sync documentation (POST /wp-json/extrachill/v1/sync/doc)
POST /event-submissions- Submit event with optional flyer
POST/DELETE /media- Upload and manage images
POST /newsletter/subscription- Subscribe to newsletterPOST /newsletter/campaign/push- Push newsletter to Sendy
GET/POST/PUT/DELETE /shop/products- Product CRUD operationsGET/POST/DELETE /shop/orders- Artist order management and fulfillmentPOST/DELETE /shop/products/{id}/images- Product image managementGET/POST/DELETE /shop/stripe- Stripe Connect managementPOST /shop/stripe-webhook- Stripe webhook handlerGET/PUT /shop/shipping-address- Artist shipping from-address managementGET/POST /shop/shipping-labels- Purchase and retrieve shipping labels
GET /stream/status- Check streaming status and configuration
POST /tools/qr-code- Generate QR codesGET /tools/markdown-export- Export content as markdown
POST /seo/audit- Start multisite SEO audit (full or batch mode)POST /seo/audit/continue- Continue paused batch auditGET /seo/audit/status- Check audit status and resultsGET /seo/audit/details- Get detailed audit results by category with pagination
See AGENTS.md for architectural patterns and docs/routes/ for complete endpoint documentation.
- WordPress 5.0+
- PHP 7.4+
- Extra Chill Platform multisite network
- Upload plugin to
/wp-content/plugins/extrachill-api/ - Network activate via Network Admin → Plugins
- Endpoints immediately available on all network sites
Add new endpoints by creating route files in inc/routes/:
<?php
/**
* Custom endpoint registration
*/
add_action('extrachill_api_register_routes', function() {
register_rest_route('extrachill/v1', '/my-endpoint', [
'methods' => 'GET',
'callback' => 'my_endpoint_callback',
'permission_callback' => '__return_true',
]);
});
function my_endpoint_callback($request) {
return rest_ensure_response(['status' => 'success']);
}Access endpoints using standard WordPress REST API patterns:
JavaScript:
fetch('/wp-json/extrachill/v1/users/search?search=username', {
method: 'GET',
headers: {
'X-WP-Nonce': wpApiSettings.nonce
}
})
.then(response => response.json())
.then(data => console.log(data));PHP:
$response = wp_remote_get(
rest_url('extrachill/v1/users/search'),
['body' => ['search' => 'username']]
);The plugin uses a singleton class to manage route discovery and prevent duplicate registrations:
ExtraChill_API_Plugin::get_instance();Routes are automatically loaded using PHP's RecursiveIteratorIterator:
- Scans
inc/routes/directory recursively - Loads all PHP files via
require_once - Supports nested directory organization
- Routes self-register using WordPress REST API
extrachill_api_bootstrap- Initialization duringplugins_loadedextrachill_api_register_routes- Route registration duringrest_api_init
extrachill-api/
├── extrachill-api.php # Main plugin file
├── build.sh # Production build script (symlink)
├── composer.json # Dependencies and scripts
├── .buildignore # Build exclusions
├── AGENTS.md # Technical documentation for AI agents
├── README.md # This file
└── inc/
├── auth/
│ └── extrachill-link-auth.php # Cross-domain authentication helper
├── activity/ # Activity system components
│ ├── db.php
│ ├── emitter.php
│ ├── emitters.php
│ ├── schema.php
│ ├── storage.php
│ ├── taxonomies.php
│ └── throttle.php
├── controllers/
│ └── class-docs-sync-controller.php
├── utils/
│ ├── bbpress-drafts.php
│ └── id-generator.php
└── routes/
├── admin/
│ ├── lifetime-membership.php
│ ├── artist-access.php
│ ├── taxonomy-sync.php
│ └── team-members.php
├── activity/
│ ├── feed.php
│ └── object.php
├── analytics/
│ ├── click.php
│ ├── link-page.php
│ └── view-count.php
├── artists/
│ ├── analytics.php
│ ├── artist.php
│ ├── links.php
│ ├── permissions.php
│ ├── roster.php
│ ├── socials.php
│ ├── subscribe.php
│ └── subscribers.php
├── auth/
│ ├── browser-handoff.php
│ ├── google.php
│ ├── login.php
│ ├── logout.php
│ ├── me.php
│ ├── refresh.php
│ └── register.php
├── blog/
│ ├── ai-adventure.php
│ ├── band-name.php
│ ├── image-voting.php
│ ├── image-voting-vote.php
│ └── rapper-name.php
├── chat/
│ ├── history.php
│ └── message.php
├── community/
│ ├── drafts.php
│ └── upvote.php
├── config/
│ └── oauth.php
├── contact/
│ └── submit.php
├── docs/
│ └── docs-info.php
├── docs-sync-routes.php
├── events/
│ └── event-submissions.php
├── media/
│ └── upload.php
├── newsletter/
│ ├── campaign.php
│ └── subscription.php
├── seo/
│ ├── audit.php
│ ├── continue.php
│ └── status.php
├── shop/
│ ├── orders.php
│ ├── product-images.php
│ ├── products.php
│ ├── shipping-address.php
│ ├── shipping-labels.php
│ ├── stripe-connect.php
│ └── stripe-webhook.php
├── stream/
│ └── status.php
├── tools/
│ └── qr-code.php
└── users/
├── artists.php
├── leaderboard.php
├── onboarding.php
├── search.php
└── users.php
cd extrachill-plugins/extrachill-api
# Install dependencies
composer install
# Run tests
composer test
# PHP linting
composer run lint:php# Create optimized production package
./build.sh
# Output: build/extrachill-api.zip# List all registered routes
wp rest list
# Test endpoint with curl
curl -X GET "http://site.local/wp-json/extrachill/v1/users/search?search=test"extrachill-blog:
- Image voting vote counts and voting
- AI Adventure story generation
- Band/Rapper name generators
extrachill-community:
- User search for @mentions
- Community upvoting
- Draft management for topics and replies
extrachill-events:
- Event submission block posts to the
/event-submissionsroute
extrachill-users:
- Avatar upload via media endpoint
- User profile and search functionality
extrachill-shop:
- Product CRUD operations
- Stripe Connect management
extrachill-newsletter:
- Newsletter subscription endpoint
- Campaign push to Sendy
All endpoints implement WordPress REST API security standards:
- Nonce Verification: WordPress REST API nonce system
- Permission Callbacks: User capability checks
- Input Validation: Parameter validation callbacks
- Sanitization: All user input sanitized
- Output Escaping: Responses via
rest_ensure_response()
- Caching: Endpoints return fresh data by default
- Query Optimization: Prepared statements and pagination
- Network-Wide: Single plugin serves all sites efficiently
- Automatic Discovery: Minimal overhead with RecursiveIteratorIterator
Required:
- WordPress 5.0+ (REST API support)
- PHP 7.4+
Recommended:
- extrachill-multisite (network-activated foundation)
Optional:
- extrachill-ai-client (for AI Adventure endpoint)
- extrachill-blog (primary endpoint consumer)
- extrachill-community (user search consumer)
- extrachill-events (event submission consumer)
- extrachill-multisite (Turnstile helpers for event submissions)
Fires after a submission is validated, optional flyer stored, and a Data Machine job is queued.
add_action( 'extrachill_event_submission', function( array $submission, array $context ) {
// $submission contains sanitized form data + optional flyer metadata
// $context includes flow_id, job_id, action_id, flow_name
} );Use the hook to notify editors, trigger Slack alerts, or log analytics without reimplementing REST validation.
- AGENTS.md - Comprehensive technical documentation for AI agents
- Root AGENTS.md - Platform-wide architectural patterns
- WordPress REST API Handbook - Official REST API documentation
For issues, questions, or feature requests related to the Extra Chill Platform:
- Primary Contact: Chris Huber - chubes.net
- Organization: Extra Chill
- Main Site: extrachill.com
GPL v2 or later
See docs/CHANGELOG.md for full version history.
Part of the Extra Chill Platform - WordPress multisite ecosystem for music community