Contesimal Connector

Description

Contesimal Connector adds REST API endpoints to your WordPress site, allowing external applications to create and manage content using an API key.

Requests are made to your site’s /wp-json/contesimal/v1/ endpoints. The plugin does not send any data externally on its own.

External services and privacy

  • Service: Designed to work with Contesimal (https://contesimal.ai), but compatible with any client using your API key.
  • Data received: Post title, content (HTML), excerpt, status, categories, tags, post type, author ID, and media URLs with optional title, alt text, caption, and description. User listing and create responses return ID, display name, slug, and roles for active users (no email or passwords in the response). Creating a user accepts username, email, optional password, display name, and an allowlisted role. The administrator role cannot be assigned via the API.
  • Media handling: Your WordPress site may download remote files from provided URLs to create Media Library attachments.
  • When: Only when a valid API request is sent to your site. No background communication occurs.
  • Control: External access is enabled only if you share the API key. You can regenerate the key or deactivate the plugin at any time.
  • Consent: By enabling the plugin and sharing the API key, the site administrator allows external applications to submit content and, when used, create users with non-administrator roles.

Authentication

All endpoints require an API key sent in the X-API-Key header (or Authorization: Bearer).

The key is:
– Generated on your site
– Stored as a secure hash
– Managed by administrators only

Requests without a valid key are rejected (401). Rate limiting is applied per IP.

API keys should be treated as sensitive credentials and only shared with trusted systems.

Features

  • API key authentication (hashed storage)
  • Create posts via REST API
  • List categories, post types, and author-capable users (with roles)
  • List assignable roles and create users (allowlisted roles only; never administrator)
  • Media import from external URLs
  • Rate limiting (per IP)
  • Configurable CORS
  • Optional request logging (admin only)
  • Contesimal admin menu: Connection, Content types, and Field mapping
  • Publish config API so Contesimal discovers enabled types and taxonomy maps

REST endpoints (base: /wp-json/contesimal/v1)

  • GET /ping – Health check
  • GET /publish-config – Enabled post types and field (categories/tags) taxonomy maps
  • GET /categories – Categories from mapped taxonomies for enabled post types
  • GET /post-types – Enabled Contesimal post types (with field maps)
  • GET /users – List active users (id, name, slug, roles; optional session_only, search, limit)
  • POST /users – Create a user with an allowlisted role
  • GET /roles – List roles that may be assigned via POST /users
  • GET /posts – List posts by enabled post type with pagination and total count
  • POST /publish – Create post (uses Field mapping for categories/tags)
  • POST /media/import – Import media from URLs (optional title, alt, caption, description)

An admin notice is shown when API access is enabled, indicating that external publishing is active.

REST API Reference

All endpoints require: X-API-Key: your_api_key

GET /wp-json/contesimal/v1/ping

Returns plugin status.

Response:
{ “status”: “ok”, “plugin”: “contesimal-connector”, “version”: “1.0.8” }

GET /wp-json/contesimal/v1/publish-config

Returns the site’s Contesimal publish map: default post type and each enabled type with whether categories/tags are mapped and to which taxonomies.

Response (example):
{ “success”: true, “default_post_type”: “post”, “post_types”: [ { “name”: “post”, “label”: “Posts”, “is_default”: true, “fields”: { “title”: true, “content”: true, “excerpt”: true, “author”: true, “featured_image”: true, “categories”: { “enabled”: true, “taxonomy”: “category” }, “tags”: { “enabled”: true, “taxonomy”: “post_tag” } } } ] }

GET /wp-json/contesimal/v1/categories

Returns active terms from taxonomies mapped as Contesimal “categories” for enabled post types. Each item includes taxonomy and post_types (enabled types that use that taxonomy for categories).

Response (example):
{ “success”: true, “categories”: [ { “id”: 1, “name”: “Uncategorized”, “slug”: “uncategorized”, “count”: 5, “taxonomy”: “category”, “post_types”: [ “post” ] } ] }

GET /wp-json/contesimal/v1/post-types

Returns post types enabled under Contesimal Content types, plus default_post_type and per-type fields (categories_taxonomy / tags_taxonomy).

GET /wp-json/contesimal/v1/users

Returns active (non-deleted / non-spam) users. Suitable for user management UI and for author_id on POST /publish. Never returns email or passwords.

Query parameters (all optional):

Parameter
Description

search
Substring match on login, nicename, display name, or email

session_only
1 to only include users with stored WordPress session tokens (typically logged in recently)

limit
Max results, 1–200 (default 200)

Response (example):
{ “success”: true, “users”: [ { “id”: 1, “name”: “admin”, “slug”: “admin”, “roles”: [ “administrator” ] } ] }

GET /wp-json/contesimal/v1/roles

Returns roles that may be assigned when creating a user. Privileged roles (e.g. administrator) are never included.

Response (example):
{ “success”: true, “roles”: [ { “slug”: “author”, “name”: “Author” }, { “slug”: “editor”, “name”: “Editor” } ] }

Default allowlist: subscriber, contributor, author, editor. Roles that exist on the site and do not grant dangerous capabilities (such as manage_options or edit_users) are returned.

POST /wp-json/contesimal/v1/users

Creates a WordPress user. Not supported on multisite. The administrator role cannot be assigned.

Headers:
Content-Type: application/json
X-API-Key: your_api_key

Body:

Field
Type
Required
Description

username
string
Yes
Login name (must be unique and valid)

email
string
Yes
Email (must be unique and valid)

password
string
No
Min 8 characters. If omitted, a strong password is generated

display_name
string
No
Display name

first_name
string
No
First name

last_name
string
No
Last name

role
string
No
Assignable role from GET /roles (default: author)

send_notification
boolean
No
Default false. If true, WordPress emails the user a link to set their password

Success response (example):
{ “success”: true, “notification_sent”: false, “user”: { “id”: 42, “name”: “Jane”, “slug”: “jane”, “roles”: [ “author” ] } }

When a password is auto-generated and send_notification is false, the response also includes "password_generated": true and "password": "…" (shown once; never stored in the activity log). When send_notification is true, the user sets their password from the email link and the plaintext password is not returned.

Error responses:
– 400 Invalid input, duplicate user, disallowed role, or multisite
– 401 Invalid API key
– 429 Rate limit exceeded
– 500 Server error

GET /wp-json/contesimal/v1/posts

Returns a paginated list of posts for a given post type, plus the total count for that filter.

Query parameters (all optional):

Parameter
Description

post_type
Public post type (default post)

per_page
1–100, default 50

offset
Number of posts to skip (default 0)

status
Comma-separated status list (default publish), or any

search
Optional keyword across title/content

Response (example):
{ “success”: true, “post_type”: “post”, “total”: 124, “per_page”: 50, “offset”: 0, “count”: 50, “posts”: [ { “post_id”: 42, “title”: “Hello world”, “slug”: “hello-world”, “status”: “publish”, “date”: “2026-05-14T11:50:00+00:00”, “author_name”: “Site Admin”, “link”: “https://example.com/hello-world/”, “featured_image”: “https://example.com/wp-content/uploads/2026/05/cover.jpg”, “featured_image_id”: 99, “categories”: [ “News”, “Updates” ], “tags”: [ “Announcement”, “WordPress” ], “content”: “

Hello

” } ] }

POST /wp-json/contesimal/v1/publish

Creates a post.

Headers:
Content-Type: application/json
X-API-Key: your_api_key

Body:

Field
Type
Required
Description

title
string
Yes
Post title

content
string
Yes
HTML content

status
string
No
publish, draft, pending, private

excerpt
string
No
Post excerpt

post_type
string
No
Default: post

category_ids
array
No
Category IDs (taxonomy category) when the post type supports categories

tags
array
No
Tag names (taxonomy post_tag) when the post type supports tags

featured_image_url
string
No
Image URL to sideload when featured_image_id is omitted

featured_image_id
integer
No
Preferred: existing Media Library attachment ID (skips re-upload)

featured_image_caption
string
No
Featured attachment Caption

featured_image_credit
string
No
Source credit (Description when description omitted)

featured_image_description
string
No
Featured attachment Description / source credit

featured_image_alt
string
No
Featured attachment alt text

featured_image_title
string
No
Featured attachment title

author_id
integer
No
Default: 1

Responses:
– 200 Success
– 400 Bad request
– 401 Invalid API key
– 429 Rate limit exceeded
– 500 Server error

Installation

  1. Upload the plugin to /wp-content/plugins/ or install via Plugins screen.
  2. Activate the plugin (API key is generated).
  3. Go to Contesimal Connection and copy your API key.
  4. Optionally enable custom post types under Content types and map categories/tags under Field mapping.
  5. Configure rate limiting, CORS, and logging if needed.
  6. Use the API key in requests via the X-API-Key header.

FAQ

Does the plugin send data externally?

No. The plugin only receives data via API requests made to your site.

Who can use the API?

Only external applications with your API key.

Can the API create administrator users?

No. Only allowlisted non-privileged roles (by default subscriber, contributor, author, editor) can be assigned. Roles with capabilities such as manage_options or edit_users are rejected.

Where is the API key managed?

In Contesimal Connection. It is shown once and stored securely as a hash.

Is this GPL compatible?

Yes, GPL v2 or later.

POST /wp-json/contesimal/v1/media/import

Imports remote media into the Media Library. Optional Media Library fields may be set on import.

Body (single URL):

Field
Type
Required
Description

url
string
Yes*
Remote http(s) URL

urls
array
Yes*
Multiple URLs (shared optional meta applies to each)

items
array
Yes*
Per-file objects with url plus optional meta

title
string
No
Attachment title

alt
string
No
Alternative text

caption
string
No
Caption

description
string
No
Description

* Provide one of url, urls, or items.

Example:
{ “url”: “https://example.com/photo.jpg”, “title”: “Summer shot”, “alt”: “Red sneakers”, “caption”: “New arrival”, “description”: “Optional longer text” }

Per-item example:
{ “items”: [ { “url”: “https://example.com/a.jpg”, “title”: “Image A”, “alt”: “Alt A” } ] }

Success results[] includes title, alt, caption, and description for each imported file.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Contesimal Connector” is open source software. The following people have contributed to this plugin.

Contributors

Translate “Contesimal Connector” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

1.0.8

  • POST /publish: optional featured image caption, credit, description, alt, and title
  • Prefer featured_image_id (reuse Media Library attachment) over re-sideloading featured_image_url

1.0.7

  • Move admin UI to a top-level Contesimal menu (Connection, Content types, Field mapping)
  • Add Content types screen to enable which public post types Contesimal may publish to
  • Add Field mapping screen to map Contesimal categories/tags to site taxonomies per post type
  • Legacy Settings Contesimal Connector URL redirects to Connection
  • Add GET /publish-config for enabled post types and category/tag taxonomy maps
  • Restrict GET /post-types, GET /posts, and POST /publish to admin-enabled types
  • GET /categories and publish/list use Field mapping taxonomies (fixes custom types such as IssueM article)

1.0.6

  • Allow category_ids and tags on POST /publish for any post type that supports those taxonomies (e.g. article), not only post

1.0.5

  • Expand GET /categories to every active category across public hierarchical taxonomies (same response shape)

1.0.4

  • Add optional title, alt, caption, and description to POST /media/import (plus per-file items)

1.0.3

  • Expand GET /users to list all active users with id, name, slug, and roles
  • Add GET /roles for assignable (non-administrator) roles
  • Add POST /users to create users with allowlisted roles, sanitized input, password generation, and optional set-password email (send_notification)

1.0.2

  • Add GET /posts to list posts by post type with pagination, total count, featured image, categories, and tags

1.0.1

  • Add GET /users to list author-capable users (ID, name, slug); optional session_only for users with active sessions

1.0.0

  • Initial stable release
  • REST API for publishing, categories, post types, and media import
  • API key authentication with hashed storage
  • Rate limiting, CORS, and optional logging
  • Admin notice for external publishing awareness