For the complete documentation index, see llms.txt. This page is also available as Markdown.

How it works

Ability naming, categories, the response envelope, permissions, and error handling

Every ACPT ability follows the same shape. Understanding this once means you can predict the request/response contract of all 57 abilities without reading each one individually.

Naming convention

All ability names use ACPT's acpt/ namespace, followed by a lowercase, hyphen-separated verb-noun pair — matching the Abilities API naming rules (lowercase alphanumeric and hyphens only, no underscores):

acpt/list-post-types
acpt/get-post-type
acpt/save-post-type
acpt/delete-post-type

Most domains expose the same four operations — list, get, save, delete — with two exceptions:

  • Taxonomies add two extra abilities to attach/detach a taxonomy from a post type: acpt/assoc-taxonomy-post-type and acpt/remove-taxonomy-post-type-assoc.

  • Form fields have no list ability, since acpt/get-form already returns a form's fields array — a separate listing ability would just duplicate it.

There's no create/update split. Every "save" ability is an upsert: it creates the item if it doesn't exist yet, or updates it in place if an item with the same natural key (post type slug, taxonomy slug, field name, form name, etc.) already exists. This mirrors ACPT's own PHP function API — see Functions — where register_acpt_post_type(), save_acpt_form(), and friends all behave the same way.

Categories

Abilities are grouped into two categories, registered on WordPress's wp_abilities_api_categories_init hook:

Category slug
Used for

acpt-content-model

Defining your content structure: custom post types, taxonomies, meta field groups/boxes/fields, option pages, forms, form fields, dynamic blocks

acpt-content-data

Reading and writing content values: field values on posts, terms, users, comments and option pages

The split matters because content-model abilities default to a stricter capability (manage_options) than content-data abilities (edit_posts) — see Permissions below.

The response envelope

Every ability's execute_callback returns one of two things:

On success, a plain array shaped like this (validated against the ability's output_schema):

  • data holds whatever the operation returns — a single object for get/save abilities, an array for list abilities, or is simply absent for delete abilities and abilities that don't return a resource (e.g. acpt/assoc-taxonomy-post-type).

  • Objects and arrays returned by ACPT's internal models are normalized into plain JSON-friendly data before being placed in data — you never receive a raw PHP object or a WP_Post_Type instance.

Each per-domain page documents the fields that are part of the stable, guaranteed response shape. In practice, data objects for meta field groups/boxes/fields, forms, dynamic blocks, and option pages may also include a handful of additional ACPT-internal bookkeeping fields (things like sort order, denormalized parent references, or computed counts) beyond what's documented — these aren't part of the guaranteed contract and may change between releases, so don't build logic against fields not listed on the relevant page.

On failure, a WP_Error instead of an array — this is standard Abilities API / WordPress convention, so any Abilities API consumer already knows how to handle it:

Two error codes are used across all ACPT abilities:

Code
Meaning

acpt_ability_failed

The underlying ACPT operation failed — invalid input, item not found, or a validation error. The message is ACPT's own error message where available, otherwise a generic per-ability fallback (e.g. "Unable to save the custom post type.").

acpt_ability_forbidden

The current user doesn't have the required capability. See Permissions.

If the input you send doesn't validate against the ability's input_schema at all, WordPress core rejects the call before ACPT's code ever runs and returns its own WP_Error — this is handled entirely by the Abilities API, not by ACPT.

Permissions

Every ability has a permission_callback that checks a WordPress capability with current_user_can():

  • Abilities in the acpt-content-model category default to manage_options.

  • Abilities in the acpt-content-data category (field values) default to edit_posts — a lower bar, since reading/writing field values is closer to everyday content editing than redesigning the content model.

Both defaults can be overridden — per-ability, per-user, or based on the input being sent — via the acpt/abilities-api/capability filter. See Extending.

Read/write/destructive metadata

Every registered ability also carries standard Abilities API annotations in its meta, so AI agents and MCP clients can reason about risk before calling something:

Annotation
Value

readonly

true for list/get abilities, false otherwise

destructive

true for delete abilities (and acpt/remove-taxonomy-post-type-assoc), false otherwise

idempotent

true for every ACPT ability — calling the same save twice with the same input produces the same end state, thanks to the upsert behavior described above

show_in_rest

true for every ACPT ability

What actually gets called

Each ability wraps an existing, already-tested piece of ACPT: either one of the documented PHP functions (register_acpt_post_type(), save_acpt_meta_group(), get_acpt_field(), …) or, where no such function exists (e.g. listing all post types), the same repository classes ACPT's admin UI uses internally. No business logic is duplicated — the Abilities API integration is purely a thin, schema-validated wrapper around ACPT's existing API surface.

Last updated