> For the complete documentation index, see [llms.txt](https://docs.acpt.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.acpt.io/developers/rest-api.md).

# REST API

ACPT REST API endpoint reference

ACPT exposes a complete REST API under the `acpt/v1` namespace. All standard WordPress REST API conventions apply.

**Base URL**

```
{site_url}/wp-json/acpt/v1
```

### Authentication

Two methods are supported:

* **Basic authentication** — `Authorization: Basic base64(username:password)`
* **API key** — `acpt-api-key: {key}-{secret}` *(recommended)* — the header value is your API key and secret joined by a hyphen (e.g. `acpt-api-key: ec73745e7f3c-bb6121f62e92`).

To generate a key/secret pair, go to **ACPT → Tools → API Dashboard**. The pair must belong to a user who can `manage_options`. See [Custom APIs](/tools/custom-apis.md) for full setup instructions.

### Interactive docs (Swagger UI)

The full OpenAPI schema is available at:

```
GET /wp-json/acpt/v1/schema
```

The ACPT admin dashboard includes a Swagger UI playground at **ACPT → Tools → API Dashboard**.

***

## Endpoints

### Custom Post Types

| Method   | Path                  | Auth     | Description                |
| -------- | --------------------- | -------- | -------------------------- |
| `GET`    | `/acpt/v1/cpt`        | Required | List all custom post types |
| `GET`    | `/acpt/v1/cpt/{slug}` | Required | Get a custom post type     |
| `POST`   | `/acpt/v1/cpt`        | Required | Create a custom post type  |
| `PUT`    | `/acpt/v1/cpt/{slug}` | Required | Update a custom post type  |
| `DELETE` | `/acpt/v1/cpt/{slug}` | Required | Delete a custom post type  |

```bash
curl -X GET "https://example.com/wp-json/acpt/v1/cpt" \
  -H "acpt-api-key: your-key-your-secret"
```

***

### Taxonomies

| Method   | Path                                   | Auth     | Description                           |
| -------- | -------------------------------------- | -------- | ------------------------------------- |
| `GET`    | `/acpt/v1/taxonomy`                    | Required | List all taxonomies                   |
| `GET`    | `/acpt/v1/taxonomy/{slug}`             | Required | Get a taxonomy                        |
| `POST`   | `/acpt/v1/taxonomy`                    | Required | Create a taxonomy                     |
| `PUT`    | `/acpt/v1/taxonomy/{slug}`             | Required | Update a taxonomy                     |
| `DELETE` | `/acpt/v1/taxonomy/{slug}`             | Required | Delete a taxonomy                     |
| `POST`   | `/acpt/v1/taxonomy/assoc/{slug}/{cpt}` | Required | Associate a taxonomy with a post type |

```bash
curl -X POST "https://example.com/wp-json/acpt/v1/taxonomy" \
  -H "acpt-api-key: your-key-your-secret" \
  -H "Content-Type: application/json" \
  -d '{"slug":"genre","singular":"Genre","plural":"Genres"}'
```

***

### Option Pages

| Method   | Path                          | Auth     | Description           |
| -------- | ----------------------------- | -------- | --------------------- |
| `GET`    | `/acpt/v1/option-page`        | Required | List all option pages |
| `GET`    | `/acpt/v1/option-page/{slug}` | Required | Get an option page    |
| `POST`   | `/acpt/v1/option-page`        | Required | Create an option page |
| `PUT`    | `/acpt/v1/option-page/{slug}` | Required | Update an option page |
| `DELETE` | `/acpt/v1/option-page/{slug}` | Required | Delete an option page |

***

### Meta Fields

| Method   | Path                 | Auth     | Description                |
| -------- | -------------------- | -------- | -------------------------- |
| `GET`    | `/acpt/v1/meta`      | Required | List all meta field groups |
| `GET`    | `/acpt/v1/meta/{id}` | Required | Get a meta field group     |
| `POST`   | `/acpt/v1/meta`      | Required | Create a meta field group  |
| `PUT`    | `/acpt/v1/meta/{id}` | Required | Update a meta field group  |
| `DELETE` | `/acpt/v1/meta/{id}` | Required | Delete a meta field group  |

```bash
curl -X GET "https://example.com/wp-json/acpt/v1/meta" \
  -H "acpt-api-key: your-key-your-secret"
```

***

### Forms

| Method   | Path                             | Auth     | Description                     |
| -------- | -------------------------------- | -------- | ------------------------------- |
| `GET`    | `/acpt/v1/form`                  | Required | List all forms                  |
| `GET`    | `/acpt/v1/form/{id}`             | Required | Get a form                      |
| `POST`   | `/acpt/v1/form`                  | Required | Create a form                   |
| `PUT`    | `/acpt/v1/form/{id}`             | Required | Update a form                   |
| `DELETE` | `/acpt/v1/form/{id}`             | Required | Delete a form                   |
| `POST`   | `/acpt/v1/form/submission/{key}` | None     | Submit a form (public endpoint) |

***

### Dynamic Blocks

| Method   | Path                  | Auth     | Description             |
| -------- | --------------------- | -------- | ----------------------- |
| `GET`    | `/acpt/v1/block`      | Required | List all dynamic blocks |
| `GET`    | `/acpt/v1/block/{id}` | Required | Get a dynamic block     |
| `POST`   | `/acpt/v1/block`      | Required | Create a dynamic block  |
| `PUT`    | `/acpt/v1/block/{id}` | Required | Update a dynamic block  |
| `DELETE` | `/acpt/v1/block/{id}` | Required | Delete a dynamic block  |

***

### WooCommerce Product Data

| Method   | Path                                                    | Auth     | Description                          |
| -------- | ------------------------------------------------------- | -------- | ------------------------------------ |
| `GET`    | `/acpt/v1/woocommerce/product-data`                     | Required | List all product data entries        |
| `GET`    | `/acpt/v1/woocommerce/product-data/{id}`                | Required | Get a product data entry             |
| `POST`   | `/acpt/v1/woocommerce/product-data`                     | Required | Create a product data entry          |
| `PUT`    | `/acpt/v1/woocommerce/product-data/{id}`                | Required | Update a product data entry          |
| `DELETE` | `/acpt/v1/woocommerce/product-data/{id}`                | Required | Delete a product data entry          |
| `GET`    | `/acpt/v1/woocommerce/product-data/{id}/fields`         | Required | List fields for a product data entry |
| `POST`   | `/acpt/v1/woocommerce/product-data/{id}/fields`         | Required | Create a field                       |
| `PUT`    | `/acpt/v1/woocommerce/product-data/{id}/fields`         | Required | Update fields                        |
| `DELETE` | `/acpt/v1/woocommerce/product-data/{id}/fields`         | Required | Delete all fields                    |
| `GET`    | `/acpt/v1/woocommerce/product-data/{id}/fields/{field}` | Required | Get a specific field                 |
| `DELETE` | `/acpt/v1/woocommerce/product-data/{id}/fields/{field}` | Required | Delete a specific field              |

***

### Filter / Query

| Method | Path                           | Auth     | Description                                            |
| ------ | ------------------------------ | -------- | ------------------------------------------------------ |
| `POST` | `/acpt/v1/{slug}/filter/query` | Required | Filter posts of a given post type by custom meta query |

```bash
curl -X POST "https://example.com/wp-json/acpt/v1/movie/filter/query" \
  -H "acpt-api-key: your-key-your-secret" \
  -H "Content-Type: application/json" \
  -d '{"filters":[{"box":"info","field":"year","value":"2024","operator":"="}]}'
```

***

### License

| Method | Path                          | Auth | Description                    |
| ------ | ----------------------------- | ---- | ------------------------------ |
| `POST` | `/acpt/v1/license/deactivate` | None | Deactivate the current license |

***

### Custom Content Types — Table Records

Table-record endpoints are only available when:

1. The table has **Expose via REST API** enabled in its General settings.
2. A valid ACPT license is active.

The record path is driven by the table's own name — there is no `table-records` prefix.

| Method   | Path                        | Auth     | Description                                                                          |
| -------- | --------------------------- | -------- | ------------------------------------------------------------------------------------ |
| `GET`    | `/acpt/v1/{tableName}`      | Required | List records in the table. Supports pagination, ordering, and filtering (see below). |
| `GET`    | `/acpt/v1/{tableName}/{id}` | Required | Get a single record by ID.                                                           |
| `POST`   | `/acpt/v1/{tableName}`      | Required | Create a new record.                                                                 |
| `PUT`    | `/acpt/v1/{tableName}/{id}` | Required | Update an existing record.                                                           |
| `DELETE` | `/acpt/v1/{tableName}/{id}` | Required | Delete a record.                                                                     |

#### List records — query parameters

| Parameter       | Type    | Description                                                                                                                       |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `page`          | integer | Page number (default: `1`).                                                                                                       |
| `per_page`      | integer | Records per page (default: `20`, max: `100`).                                                                                     |
| `order_by`      | map     | Column → direction map. Repeat the key per column, e.g. `?order_by[year]=DESC&order_by[title]=ASC`. Direction is `ASC` or `DESC`. |
| `filters`       | string  | URL-encoded JSON array of filter objects (see below).                                                                             |
| `s`             | string  | Free-text search across the columns marked *Show in archive*.                                                                     |
| `record_status` | string  | `active` (default) or `trash`. Only meaningful when the table has **Soft delete** enabled.                                        |

Each `filters` object is `{ "column": "...", "operator": "...", "value": "...", "logic": "AND" }`:

| Operator                    | Meaning                                         |
| --------------------------- | ----------------------------------------------- |
| `equals` *(default)*        | `column = value`                                |
| `not_equals`                | `column != value`                               |
| `contains`                  | `column LIKE %value%`                           |
| `starts_with`               | `column LIKE value%`                            |
| `greater_than`              | `column > value`                                |
| `less_than`                 | `column < value`                                |
| `is_empty` / `is_not_empty` | `column IS NULL` / `IS NOT NULL` (omit `value`) |

`logic` (`AND` / `OR`, default `AND`) chains an object with the next one.

```bash
# Movies from 2015 onwards, newest first
curl -G "https://example.com/wp-json/acpt/v1/movies" \
  -H "acpt-api-key: your-key-your-secret" \
  --data-urlencode 'order_by[year]=DESC' \
  --data-urlencode 'filters=[{"column":"year","operator":"greater_than","value":"2014"}]'
```

#### Create a record

```bash
curl -X POST "https://example.com/wp-json/acpt/v1/movies" \
  -H "acpt-api-key: your-key-your-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Blade Runner 2049",
    "year": 2017,
    "director_id": 1
  }'
```

#### File uploads

For columns of type `Image`, `File`, `Video`, or `Audio`, use `multipart/form-data`:

```bash
curl -X POST "https://example.com/wp-json/acpt/v1/movies" \
  -H "acpt-api-key: your-key-your-secret" \
  -F "title=Blade Runner 2049" \
  -F "year=2017" \
  -F "poster=@/path/to/poster.jpg"
```

#### Response format

**List** (`GET /acpt/v1/{tableName}`) — a pagination envelope:

```json
{
  "currentPage": 1,
  "prev": null,
  "next": "https://example.com/wp-json/acpt/v1/movies?page=2&per_page=20",
  "total": 42,
  "records": [
    {
      "id": 1,
      "title": "Blade Runner 2049",
      "year": 2017,
      "director_id": 1,
      "created_at": "2026-06-08 10:00:00",
      "updated_at": "2026-06-08 10:00:00"
    }
  ]
}
```

`prev` / `next` are ready-to-use URLs, or `null` at the ends of the range.

**Single record** (`GET /acpt/v1/{tableName}/{id}`) — the bare object:

```json
{
  "id": 1,
  "title": "Blade Runner 2049",
  "year": 2017,
  "director_id": 1,
  "created_at": "2026-06-08 10:00:00",
  "updated_at": "2026-06-08 10:00:00"
}
```
