# Extending the REST API FluentCRM provides a Laravel-like routing framework (WPFluent) that lets you register custom REST API endpoints under the FluentCRM namespace. Your endpoints get the same policy-based authorization, request handling, and validation that FluentCRM's built-in 226 routes use. ## Base URL All FluentCRM REST endpoints are served under: ``` https://yourdomain.com/wp-json/fluent-crm/v2/ ``` Custom endpoints you register appear under this same base with your chosen prefix. ## Authentication FluentCRM uses WordPress cookie-based authentication with nonce verification — the same mechanism as the WordPress admin. There is no separate API key system. Requests must include a valid `wp_rest` nonce, which is automatically handled when making requests from the WordPress admin. ## Quick Start Here's a complete example that adds a custom endpoint at `/wp-json/fluent-crm/v2/my-plugin/stats`: **Register routes** — Hook into `fluentcrm_loaded` to access the router: ```php // my-plugin.php add_action('fluentcrm_loaded', function ($app) { $app->router ->prefix('my-plugin') ->withPolicy('MyPlugin\Policies\MyPolicy') ->group(function ($router) { $router->get('/', 'MyPlugin\Controllers\MyController@index'); $router->get('/stats', 'MyPlugin\Controllers\MyController@stats'); $router->post('/sync', 'MyPlugin\Controllers\MyController@sync'); }); }); ``` **Controller** — Extend the base controller: ```php sendSuccess([ 'message' => __('My Plugin API is active', 'my-plugin'), ]); } public function stats() { $data = [ 'total_synced' => get_option('my_plugin_synced_count', 0), 'last_sync' => get_option('my_plugin_last_sync', ''), ]; return $this->sendSuccess($data); } public function sync() { $this->validate($this->request->all(), [ 'source' => 'required|string', ]); $source = sanitize_text_field($this->request->get('source')); // ... perform sync logic return $this->sendSuccess([ 'message' => __('Sync completed', 'my-plugin'), ]); } } ``` **Policy** — Control who can access your endpoints: ```php currentUserCan('fcrm_manage_contacts'); } } ``` ::: tip Make sure your classes are autoloaded (via Composer or a custom autoloader) before the `fluentcrm_loaded` action fires. ::: ## Directory Structure A typical plugin extending FluentCRM's REST API: ``` my-plugin/ ├── my-plugin.php # Route registration ├── composer.json # PSR-4 autoloading ├── Controllers/ │ └── MyController.php └── Policies/ └── MyPolicy.php ``` With `composer.json` autoloading: ```json { "autoload": { "psr-4": { "MyPlugin\\": "" } } } ``` ## Next Steps | Page | Covers | |------|--------| | [Routing](./rest-api-routing) | HTTP methods, route groups, prefixes, parameter constraints | | [Controllers](./rest-api-controllers) | Request handling, validation rules, response methods | | [Policies & Permissions](./rest-api-policies) | Authorization, FluentCRM capabilities, middleware | **Source:** `vendor/wpfluent/framework/src/WPFluent/Http/Router.php`