Skip to main content

WordPress ExecModule

Overview

WordPressModule connects ValkyrAI workflows to the WordPress REST API v2 through the native map I/O ExecModule ABI. It covers the post, page, user-discovery, and taxonomy action families emphasized by n8n while enforcing ValkyrAI's IntegrationAccount, validation, retry, redaction, and observability contracts.

The module provides 14 operations: create, get, list, update, and delete for posts and pages; category and tag listing; and read-only user get/list. GET requests retry transient failures conservatively. Creates, updates, and deletes are single-attempt because a transport failure can leave their provider outcome ambiguous. Content deletion moves records to trash by default; permanent deletion requires two explicit controls.

Usage

  1. Use WordPress 5.6 or newer with HTTPS, REST API access, and Application Passwords enabled.
  2. Create a dedicated WordPress user with only the capabilities required for the workflow.
  3. Generate an Application Password for that user.
  4. Store the username in encrypted IntegrationAccount.username, the Application Password in encrypted IntegrationAccount.password, and the public site origin in IntegrationAccount.accountId.
  5. Set the account status to READY and bind it through ExecModuleConfig.authConfig.integrationAccount.
  6. Choose one documented operation and provide only its typed resource ID, record, filters, and pagination controls.
  7. Require human or policy approval before enabling permanent deletion.

Credentials, authorization headers, arbitrary HTTP methods, alternate REST namespaces, insecure TLS, and private-network targets cannot come from workflow input.

Inputs

NameTypeRequirementDefaultDescription and constraints
operationstringRequiredNoneOne of the 14 documented operations.
siteUrlstringRequired unless the account supplies itIntegrationAccount.accountIdPublic HTTPS WordPress origin, optionally with a bounded subdirectory. Credentials, custom ports, query strings, fragments, localhost, and IP literals are rejected.
resourceIdintegerGet/update/deleteNonePositive post, page, or user ID.
recordobjectCreate/updateNoneNon-empty post/page allowlist; at most 40 properties and 512 KiB. Credential-like fields are rejected.
queryobjectOptional list filter{}Up to 24 resource-specific filters with bounded scalar or scalar-array values.
pageintegerOptional list start1First provider page, 1–100,000.
perPageintegerOptional100WordPress page size, 1–100.
returnAllbooleanOptionalfalseFollow pages until exhaustion or the 10,000-item safety cap.
forceDeletebooleanDelete onlyfalsefalse requests reversible trash; true requests permanent deletion.
confirmPermanentDeletebooleanPermanent delete onlyfalseMust be true when forceDelete is true.
timeoutMsintegerOptional30000Total/connect/read/write timeout, 100–300,000 ms.

Create operations require a bounded record.title. Allowed content fields include title, content, excerpt, status, slug, author, featured media, discussion status, template, metadata, and publication date. Posts additionally support format, sticky state, category IDs, and tag IDs; pages support parent and menu order. Password-protected content and user/password writes are intentionally excluded so workflow payloads do not carry credentials.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation name.
resourcestringValid operationposts, pages, categories, tags, or users.
data / idobject / integerSingle-resource successProvider resource and verified positive ID.
items / countarray / integerList successBounded collection resources and emitted count.
hasMore / nextPageboolean / integerList successProvider pagination state from X-WP-TotalPages.
httpStatusintegerSingle-resource successWordPress HTTP status.
attemptsintegerAlwaysTotal provider attempts, including page reads.
errorobjectFailureSafe {code, message, retryable} details.

Application Passwords, Basic authorization values, and credential-bearing provider text are redacted from errors and outputs.

IntegrationAccount Requirements

SettingRequirement
ProviderWordPress REST API v2 site
accountNameHuman-readable editorial automation identity
accountIdPublic HTTPS site origin, for example https://content.example.com
usernameDedicated WordPress username or account email
passwordEncrypted WordPress Application Password
statusREADY; every other status fails closed
CapabilityMinimum WordPress role/capabilities for the selected reads or approved content writes

Application Passwords inherit the WordPress user's capabilities. Use a dedicated minimum-access user, rotate the password through the IntegrationAccount lifecycle, revoke unused passwords, and never place the username/password pair in workflow JSON.

Configuration

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:wordpress-editorial"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 5000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_posts\",\"perPage\":50,\"query\":{\"status\":\"publish\"}}"
}
}

The integration-account value is symbolic. Persisted workflows use the generated relationship, not embedded credentials.

Operations

OperationWordPress behaviorSide effect
create_postCreates a post from bounded editorial, taxonomy, discussion, and publication fields.Content write; single attempt.
get_postReads one post by ID.Read-only; safe retries.
list_postsLists posts by status, search, author, taxonomy, time, slug, and ordering filters.Read-only; paginated safe retries.
update_postUpdates allowlisted post fields and verifies the returned ID.Content write; single attempt.
delete_postMoves a post to trash by default or permanently deletes after explicit confirmation.Reversible by default; single attempt.
create_pageCreates a page with bounded hierarchy, order, template, and editorial fields.Content write; single attempt.
get_pageReads one page by ID.Read-only; safe retries.
list_pagesLists pages by status, search, author, parent, time, slug, and ordering filters.Read-only; paginated safe retries.
update_pageUpdates allowlisted page fields and verifies the returned ID.Content write; single attempt.
delete_pageMoves a page to trash by default or permanently deletes after explicit confirmation.Reversible by default; single attempt.
list_categoriesLists category taxonomy terms with bounded filters.Read-only; paginated safe retries.
list_tagsLists tag taxonomy terms with bounded filters.Read-only; paginated safe retries.
get_userReads one visible WordPress user by ID.Read-only; safe retries.
list_usersLists visible users by role, publication, search, slug, and ordering filters.Read-only; paginated safe retries.

Errors and Failure Modes

CodeTypical causeRetryableResolution
VALIDATION_ERRORInvalid origin, credential, ID, body, status, taxonomy IDs, filter, timestamp, pagination, or delete acknowledgement.NoCorrect the named field; validation failures send no request.
UNSUPPORTED_OPERATIONUnknown operation.NoSelect a documented operation.
INTEGRATION_ACCOUNT_REQUIREDNo bound account.NoBind a WordPress IntegrationAccount.
INTEGRATION_ACCOUNT_NOT_READYAccount is not READY.NoRepair or reconnect the account.
WORDPRESS_REST_*WordPress returned a structured REST error.Depends on statusCorrect site capabilities, resource state, or payload.
WORDPRESS_HTTP_401 / 403Username/Application Password is invalid, revoked, or under-scoped.NoRotate the password or grant the minimum required capability.
WORDPRESS_HTTP_404Resource or REST route is absent.NoVerify REST API availability, permalinks, and the resource ID.
WORDPRESS_HTTP_429 / 5xxRate limit or transient site failure.Yes for readsHonor Retry-After; reconcile writes before repeating them.
NETWORK_ERRORDNS, TLS, timeout, or connectivity failure.Yes for readsVerify the site; never blindly retry an ambiguous mutation.
RESPONSE_TOO_LARGEOne response exceeded 5 MiB.NoNarrow filters or lower perPage.
RESOURCE_ID_MISMATCHA single-resource response returned another ID.NoStop and reconcile proxy/plugin behavior before retrying.

Example

Publish an approved platform update:

{
"operation": "create_post",
"siteUrl": "https://content.example.com",
"record": {
"title": "Quarterly platform update",
"content": "<p>Highlights from the quarter...</p>",
"status": "publish",
"slug": "quarterly-platform-update",
"categories": [7],
"tags": [19]
}
}

Expected result:

{
"status": "success",
"operation": "create_post",
"resource": "posts",
"id": 842,
"httpStatus": 201,
"attempts": 1,
"data": {"id": 842, "status": "publish", "slug": "quarterly-platform-update"}
}

Notes

  • Pagination: list operations set page and per_page, consume X-WP-TotalPages, stop after one page unless returnAll is enabled, and cap aggregate results at 10,000.
  • Rate limits: GET operations retry HTTP 408, 429, 500, 502, 503, and 504 up to three attempts with bounded backoff and integer Retry-After. Mutations never retry automatically.
  • API limits: responses are capped at 5 MiB, records at 512 KiB and 40 fields, filters at 24 fields, page size at 100, and aggregate results at 10,000. Origins, strings, arrays, IDs, and timestamps are validated before dispatch.
  • Idempotency: get/list operations are safe reads. Create, update, and delete are not assumed idempotent; a timeout is ambiguous and requires provider reconciliation. Use stable slugs and caller correlation data where the editorial process supports them.
  • Destructive behavior: delete requests use force=false by default, which asks WordPress to move supported content to trash. Permanent deletion requires both forceDelete: true and confirmPermanentDelete: true.
  • Privacy: user responses and private/draft content can contain personal or confidential information. Limit downstream propagation, logging, retention, and workflow audiences.
  • Routing: production requests use the validated public HTTPS site origin plus the fixed /wp-json/wp/v2 namespace. HTTP downgrade, embedded credentials, custom ports, arbitrary paths, localhost, and IP literals are rejected.
  • External verification: request construction, Basic authentication, pagination, validation, retry safety, response mapping, ID checks, redaction, and metadata discovery are deterministic local tests. Live WordPress roles, plugins, themes, REST filters, reverse proxies, and provider data require separately authorized site credentials and are not exercised in repository tests.
  • Deferred operations: media upload, comments, revisions, custom post types, custom taxonomies, user create/update/delete, password-protected content, WordPress.com OAuth2, webhooks/triggers, batch endpoints, and arbitrary raw requests.
  • Functional references: n8n WordPress integration source, WordPress REST API handbook, and WordPress Application Passwords guide.