Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [Getting Started](docs/2.getting-started.md)
- [Registering Abilities](docs/3.registering-abilities.md)
- [Using Abilities](docs/4.using-abilities.md)
- [REST API Reference](docs/5.rest-api.md)
- [Contributing Guidelines](CONTRIBUTING.md)

## Inspiration
Expand All @@ -33,7 +34,7 @@
## Current Status

| Milestone | State |
| ----------------------------------- |-------------|
| ----------------------------------- | ----------- |
| Placeholder repository | **created** |
| Spec draft | in progress |
| Prototype plugin & Composer package | in progress |
Expand Down
200 changes: 200 additions & 0 deletions docs/5.rest-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# 5. REST API Reference

The WordPress Abilities API provides REST endpoints that allow external systems to discover and execute abilities via HTTP requests.

## User access

Access to all Abilities REST API endpoints requires an authenticated user (see the [Authentication](#authentication) section). Access to execute individual Abilities is restricted based on the `permission_callback()` of the Ability.

## Schema

The Abilities API endpoints are available under the `/wp/v2/abilities` namespace.

### Ability Object

Abilities are represented in JSON with the following structure:

```json
{
"name": "my-plugin/get-site-info",
"label": "Get Site Information",
"description": "Retrieves basic information about the WordPress site.",
"output_schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Site name"
},
"url": {
"type": "string",
"format": "uri",
"description": "Site URL"
}
}
},
"meta": {}
}
```

## List Abilities

### Definition

`GET /wp/v2/abilities`

### Arguments

- `page` _(integer)_: Current page of the collection. Default: `1`.
- `per_page` _(integer)_: Maximum number of items to return per page. Default: `50`, Maximum: `100`.

### Example Request

```bash
curl https://example.com/wp-json/wp/v2/abilities
```

### Example Response

```json
[
{
"name": "my-plugin/get-site-info",
"label": "Get Site Information",
"description": "Retrieves basic information about the WordPress site.",
"output_schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Site name"
},
"url": {
"type": "string",
"format": "uri",
"description": "Site URL"
}
}
},
"meta": {}
}
]
```

## Retrieve an Ability

### Definition

`GET /wp/v2/abilities/(?P<namespace>[a-z0-9-]+)/(?P<ability>[a-z0-9-]+)`

### Arguments

- `namespace` _(string)_: The namespace part of the ability name.
- `ability` _(string)_: The ability name part.

### Example Request

```bash
curl https://example.com/wp-json/wp/v2/abilities/my-plugin/get-site-info
```

### Example Response

```json
{
"name": "my-plugin/get-site-info",
"label": "Get Site Information",
"description": "Retrieves basic information about the WordPress site.",
"output_schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Site name"
},
"url": {
"type": "string",
"format": "uri",
"description": "Site URL"
}
}
},
"meta": {}
}
```

## Execute an Ability

### Definition

`POST /wp/v2/abilities/(?P<namespace>[a-z0-9-]+)/(?P<ability>[a-z0-9-]+)/run`

### Arguments

- `namespace` _(string)_: The namespace part of the ability name.
- `ability` _(string)_: The ability name part.
- `input` _(integer|number|boolean|string|array|object|null)_: Optional input data for the ability as defined by its input schema.

### Example Request (No Input)

```bash
curl -X POST https://example.com/wp-json/wp/v2/abilities/my-plugin/get-site-info/run
```

### Example Request (With Input)

```bash
curl -X POST \
-H "Content-Type: application/json" \
-d '{"input":{"option_name":"blogname","option_value":"New Site Name"}}' \
https://example.com/wp-json/wp/v2/abilities/my-plugin/update-option/run
```

### Example Response (Success)

```json
{
"name": "My WordPress Site",
"url": "https://example.com"
}
```

### Example Response (Error)

```json
{
"code": "ability_invalid_permissions",
"message": "Ability \"my-plugin/update-option\" does not have necessary permission.",
"data": {
"status": 403
}
}
```

## Authentication

The Abilities API supports all WordPress REST API authentication methods:

- Cookie authentication (same-origin requests)
- Application passwords (recommended for external access)
- Custom authentication plugins

### Using Application Passwords

```bash
curl -u 'USERNAME:APPLICATION_PASSWORD' \
https://example.com/wp-json/wp/v2/abilities
```

## Error Responses

The API returns standard WordPress REST API error responses with these common codes:

- `ability_missing_input_schema` – the ability requires input but none was provided.
- `ability_invalid_input` - input validation failed according to the ability's schema.
- `ability_invalid_permissions` - current user lacks permission to execute the ability.
- `ability_invalid_output` - output validation failed according to the ability's schema.
- `ability_invalid_execute_callback` - the ability's execute callback is not callable.
- `rest_ability_not_found` - the requested ability is not registered.
- `rest_ability_invalid_method` - the requested HTTP method is not allowed for executing the selected ability.
- `rest_ability_cannot_execute` - the ability cannot be executed due to insufficient permissions.
2 changes: 1 addition & 1 deletion tests/unit/rest-api/wpRestAbilitiesRunController.php
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public function test_resource_ability_requires_get(): void {
/**
* Test output validation against schema.
* Note: When output validation fails in WP_Ability::execute(), it returns null,
* which causes the REST controller to return 'rest_ability_execution_failed'.
* which causes the REST controller to return 'ability_invalid_output'.
*/
public function test_output_validation(): void {
$request = new WP_REST_Request( 'POST', '/wp/v2/abilities/test/invalid-output/run' );
Expand Down