Contents
On this page

Plugixa Testimonial REST API - Plugixa Testimonial

The integration surface for Plugixa Testimonial: testimonials you can list, create, edit, moderate, reorder and delete, categories and custom fields, e-mailed testimonial requests, saved views and shortcodes, import and export, translations, and the public routes the front end uses. Enough to sync testimonials from a CRM or a review platform, feed a headless site, or automate moderation.

The admin app uses these same routes, under the namespace plugixatestimonial/v1 (one word, no hyphen), so anything the admin can do with content, a script can do too. Every capability the interface checks is checked again at the endpoint.

Base URL

https://your-site.example/wp-json/plugixatestimonial/v1

On a site with plain permalinks, pass the route as a parameter instead:

https://your-site.example/?rest_route=/plugixatestimonial/v1/testimonials

Authentication

Plugixa Testimonial has no API keys of its own. It uses standard WordPress authentication:

Caller How it signs in
A script or another system A WordPress Application Password, sent as HTTP Basic auth
The admin app, or your own code in wp-admin The logged-in cookie plus a wp_rest nonce in X-WP-Nonce, the normal WordPress way
The front end (lists, the submission form, request links, social proof) Nothing: those routes are public

Create an Application Password under Users -> Profile -> Application Passwords for the user the script should act as, then send it with the username:

curl -s "https://your-site.example/wp-json/plugixatestimonial/v1/testimonials" \
  -u "admin:$WP_APP_PASSWORD"

WordPress only accepts Application Passwords over HTTPS. A request that arrives signed out is refused with 403, not 401.

Capabilities

Each route checks one of four gates. The plugin gives its capabilities to the Administrator role on activation, and each gate except the last also accepts a WordPress capability, so an untouched site works without a role editor:

Gate Plugin capability Or WordPress capability Used by
Edit plugixa_testimonial_edit edit_posts (Contributors and up) Reading, creating and updating testimonials, categories, views and shortcodes; reordering; translations
Delete plugixa_testimonial_delete delete_others_posts (Editors and up) Deleting testimonials, categories, views and shortcodes; unlinking translations
Approve plugixa_testimonial_approve publish_posts (Authors and up) Change Status and Bulk Action
Admin none manage_options only Custom fields, testimonial requests, import and export

plugixa_testimonial_manage and plugixa_testimonial_settings exist but no route checks them.

Responses

Every successful response is wrapped the same way, with status 200, creates included:

{
  "success": true,
  "message": "Testimonial created successfully",
  "data": { "id": 42 }
}

message is a translated confirmation, empty on reads. A create answers only the new id in data.id: read the record back if you need it. File exports are the exception: they answer with the file itself.

Records are returned as they are stored. Numbers read from the database come back as strings ("id": "42", "rating": "5", "is_featured": "1"), null stays null, and datetimes are in the site’s time zone as 2026-11-12 09:30:00, not UTC. A request’s expires_at is the one datetime stored in UTC. Ids and counts the plugin computes itself (a new id, total) are real integers. Cast before you compare.

Lists and pagination

Paged list endpoints accept the same parameters and put the total in the body, not in headers (X-WP-Total is not sent).

Parameter Type Default Description
limit integer 20 Rows per page. 0 or -1 returns every row; there is no upper limit
offset integer 0 Rows to skip
orderby string created_at One of the sortable columns each endpoint lists
order string DESC ASC or DESC, in capitals: desc is rejected with 400
filter[...] object The filters each endpoint lists, such as filter[rating_min]=4
lang string With WPML or Polylang active: only rows in this language
group_by_translation string With WPML or Polylang active: send 1 for only default-language rows (plus rows with no translation group). Any non-empty value except 0 turns it on, false included

search and status can also be sent at the top level. A page answers like this:

{
  "success": true,
  "message": "",
  "data": {
    "items": [ { "id": "42", "client_name": "Sarah Johnson" } ],
    "total": 37,
    "state": { "filter": { "status": "approved" }, "limit": 20, "offset": 0, "orderby": "created_at", "order": "DESC" }
  }
}

To walk every page, add limit to offset until offset reaches total, or send limit=-1. With WPML or Polylang active, rows also carry a translations list of { id, language_code }. There is no trash: deleted rows are gone. The public front-end lists page differently, with page and per_page: see List Approved Testimonials.

Endpoints

Resource Endpoints
Testimonials List, Create, Get, Update, Delete, Change status, Reorder, Delete several, Bulk action, Authors
Categories List, Create, Get, Update, Delete, Reorder
Custom fields List, Create, Get, Update, Delete, Reorder
Requests List, Send, Get, Delete, Resend, Send several, Delete several, Check token (public)
Views List, Create, Get, Update, Delete, Duplicate, Set default, Delete several
Shortcodes List, Create, Get, Update, Delete, Duplicate, Delete several
Exports CSV, JSON, PDF PRO
Imports Upload file, Run import
Front end (public) Approved testimonials, Rendered page, Submit, Social proof
Translations Languages, List, Create, Link, Unlink

Everything except the PDF export is in the free build. The PRO route is registered only by the Pro build: on the free build it is not there at all and answers 404, rather than an upgrade message. Settings, the dashboard, the admin’s pickers and previews, font loading, demo data and the Pro Google, Facebook and review-source connections also live under this namespace, but they serve the admin screens and are not covered here.

Updates are not all alike

The single thing most likely to cost you an afternoon:

Endpoint What a field you leave out does
Update Testimonial Resets rating, is_featured and display_order, and sets status back to pending, which unpublishes it. Other fields are kept
Update Category Resets everything, and an omitted slug is saved empty
Update Custom Field Resets everything except the key
Update View Keeps name, slug and description, but takes the default flag off and rebuilds a sent config from the defaults
Update Shortcode Keeps name, slug and description, but rebuilds a sent config from the defaults

Each answers 200 even when nothing matched the id. Read the record, merge your change into it, and send the whole thing back.

Errors

Errors use the standard WordPress shape. The plugin’s own errors carry the code rest_error and an errors object, which names the fields for a validation failure and is empty otherwise:

{
  "code": "rest_error",
  "message": "Validation failed",
  "data": {
    "status": 400,
    "errors": { "testimonial_text": "Testimonial text must be at least 10 characters" }
  }
}

These can come back from any endpoint. Each endpoint page lists its own errors on top of them.

Status Code When
403 rest_forbidden The user lacks the capability, or the request arrived signed out (no credentials, or a cookie without a valid nonce).
401 WordPress’s own The Application Password or username is wrong. WordPress rejects it before the plugin runs.
403 rest_cookie_invalid_nonce A cookie request sent a stale or wrong X-WP-Nonce.
404 rest_no_route No such route or method, or the PRO route on the free build.
400 rest_invalid_param A parameter failed validation, for example order=desc in lower case, limit below -1, or a status or rating outside the allowed values.
400 rest_missing_callback_param A required parameter is missing.
500 rest_error The database refused a write. The message says which operation failed.

There is no rate limit on any route. The public submission route has none either, which is why reCAPTCHA is worth turning on for a public form: see Submission settings.

Caching

The public front-end lists are cached. Any write to this namespace (any request that is not a GET) clears that cache, so changes made through the API show at once. Changes written to the database by other means do not clear it.

No filter changes what these routes return. To change behaviour in PHP, see Hooks.

Troubleshooting

Symptom Usual cause
A testimonial disappeared from the site after an update PUT /testimonials/{id} was sent without status, which resets it to pending. Send the full record.
The site lost its default view PUT /views/{id} was sent without is_default: true, or Set Default View was given an id that does not exist.
A category update fails with 500 Another category already has an empty slug. Always send slug.
Every imported row fails with “Missing client name” mapping was keyed by column name. Key it by column position: "0", "1", …
400 with order Send ASC or DESC in capitals.
"id": "42" compared with 42 fails Values read from the database are strings. Cast them.
404 from every route The namespace is plugixatestimonial/v1, without a hyphen.
404 on the PDF export The free build does not register it. Check which build is installed.
403 from a script Missing or wrong credentials, or a user without the capability. Custom fields, requests and import/export need an Administrator.
403 from the browser The nonce is missing or stale. Reload the page.

See also

Quick Links

Share