Contents
On this page
Plugixa Team REST API - Plugixa Team
The integration surface for Plugixa Team: members you can list, create, edit, reorder and delete, the groups they belong to, the custom fields defined for them PRO, and the public submission form PRO. Enough to sync a staff directory from an HR system, feed a headless front end, or collect submissions from your own form.
Authentication. Plugixa Team has no API keys of its own. A script signs in the normal WordPress way, with an Application Password, and can do what that WordPress user can do in the Plugixa Team admin. Two public endpoints, for the submission form, need no sign-in at all.
Everything the admin app does with members, groups and custom fields, it does over this API, under the namespace plugixateam/v1. Every permission the interface enforces is enforced at the endpoint rather than in the page.
Base URL
https://your-site.example/wp-json/plugixateam/v1
On a site with plain permalinks, pass the route as a parameter instead:
https://your-site.example/?rest_route=/plugixateam/v1/members
Authentication
Create an Application Password under Users -> Profile -> Application Passwords for the WordPress user the script should act as, then send it with HTTP Basic authentication:
curl -s "https://your-site.example/wp-json/plugixateam/v1/members" \
-u "admin:$WP_APP_PASSWORD"
WordPress offers Application Passwords on sites served over HTTPS. Some hosts strip the Authorization header before PHP sees it; on those, the request arrives signed out and is refused with 403.
| Caller | How it signs in |
|---|---|
| A script or another system | A WordPress Application Password |
| The admin app and the Team block | The logged-in cookie plus a wp_rest nonce, the normal WordPress way |
| The submission form | Nothing: its two endpoints are public |
Capabilities
What a user may do is decided by WordPress capabilities. Activating the plugin gives administrators all four and editors plugixa_team_edit. A role editor can grant them to other roles.
| Capability | Allows | Also accepted |
|---|---|---|
plugixa_team_edit |
List, read, create, edit, reorder and change the status of members; create, edit and reorder groups; read custom field definitions | manage_options |
plugixa_team_edit (groups, read only) |
List and read groups | edit_posts, for the group picker in the Team block |
plugixa_team_delete |
Delete members and groups, one at a time or in bulk | manage_options |
plugixa_team_settings |
Create, edit, reorder and delete custom field definitions PRO | manage_options |
An editor can therefore manage the team but cannot delete anyone. Settings, views, shortcodes, translations, import and export, the AI generator and demo data are admin features and are not part of this reference.
Responses
Every successful response is wrapped the same way, with HTTP 200, creations included:
{
"success": true,
"message": "Member created successfully",
"data": { "id": 57 }
}
message is a translated confirmation on writes and empty on reads. Creating and updating return only the id: read the record back when you need it.
Note. Member, group and custom field rows come back as the database stores them, so numbers and flags are strings:
"id": "57","is_featured": "1","member_count": "4". Ids in write responses, group lists inside a member, and the custom field flags (is_required,show_in_frontend,show_in_form) are real integers and booleans. Datetimes are in the site’s time zone, as2026-11-12 09:30:00.
Lists and pagination
The list endpoints page with limit and offset, not page and per_page:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer |
20 |
Rows to return. 0 or less returns every row |
offset |
integer |
0 |
Rows to skip |
orderby |
string |
created_at |
One of the columns each endpoint lists. Anything else falls back to that endpoint’s default column |
order |
string |
DESC |
ASC or DESC, in upper case. asc is refused with 400 |
search |
string |
Text search over the columns each endpoint lists | |
filter |
object |
Endpoint filters, sent as filter[status]=draft. A JSON string is refused |
The totals are in the body, not in headers (X-WP-Total is not sent):
{
"success": true,
"message": "",
"data": {
"items": [],
"total": 14,
"state": { "filter": [], "limit": 20, "offset": 20, "orderby": "created_at", "order": "DESC" }
}
}
data.total counts every match before paging; data.state echoes what was applied. There is no trash: a deleted row is gone.
Endpoints
| Resource | Endpoints |
|---|---|
| Members | List, Create, Get, Update, Delete, Update status, Reorder, Bulk delete, Bulk update, Departments |
| Groups | List, Create, Get, Update, Delete, Reorder |
| Custom fields PRO | List, Create, Get, Update, Delete, Reorder |
| Submissions PRO | Submit member, Public custom fields |
Custom field values are not a resource of their own: they travel with each member, in its meta object.
Errors
Errors use the standard WordPress shape. The plugin’s own errors all use the code rest_error, so tell them apart by status, and read data.errors for field-level messages:
{
"code": "rest_error",
"message": "Validation failed",
"data": {
"status": 400,
"errors": {
"first_name": "First name is required"
}
}
}
These can come back from any endpoint. Each endpoint page lists its own errors on top of them.
| Status | Code | When |
|---|---|---|
401 |
incorrect_password, invalid_username |
WordPress rejected the Application Password or the user name. |
403 |
rest_forbidden |
Signed out, or the user lacks the capability. The plugin answers 403 in both cases, never 401. |
403 |
rest_cookie_invalid_nonce |
A cookie-authenticated request with a missing or stale nonce. |
404 |
rest_no_route |
No such route or method. Custom field and submission routes answer this on the free build. |
400 |
rest_invalid_param |
A parameter has the wrong type or value, for example order=asc. |
400 |
rest_missing_callback_param |
A required parameter is missing. |
Rate limit
Only Submit Member is rate-limited: 5 attempts per 15 minutes per IP address, failed attempts included, answered with 429 beyond that. The signed-in endpoints have no limit.
The address is the one the web server sees. Behind a CDN or reverse proxy, every visitor shares the proxy’s address and so one allowance. Return the real visitor address from the plugixateam_rate_limit_client_ip filter, taken from a header your proxy sets and that visitors cannot forge:
add_filter( 'plugixateam_rate_limit_client_ip', function ( string $ip ) {
// Cloudflare sets this header on every request it forwards.
return $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $ip;
} );
Troubleshooting
| Symptom | Usual cause |
|---|---|
403 from a script |
The host strips Authorization, the user lacks the capability, or the Application Password is for another user. |
403 on delete only |
Editors can edit but not delete. Use an administrator, or grant plugixa_team_delete. |
400 rest_invalid_param on a list |
order must be ASC or DESC in upper case, and filters go in filter[...]. |
| A draft member went live after an update | An update without status sets it to published. Send the status back. |
| A group’s slug is empty after an update | An update without slug empties it. Send the slug back. |
404 on /custom-fields or /frontend/... |
The site runs the free build. |
429 from the submission form for everyone |
The site is behind a proxy: see Rate limit. |
See also
- How members, groups and fields work in the admin: Members, Groups, Custom Fields PRO.
- The form behind the public endpoints: Submission form PRO.
- Change behaviour in PHP instead: Hooks.
Quick Links
Share