Contents
On this page

Create Recipe - Plugixa Recipe

POST /plugixa-recipe/v1/recipes

Create a recipe with its ingredients, instructions, taxonomy links and nutrition in one request.

Needs the plugixa_recipe_edit capability, or WordPress’s edit_posts (Contributor and up). When the request moves the recipe into or out of published, it also needs plugixa_recipe_publish or WordPress’s publish_posts (Author and up). Moving between draft, pending and archived does not.

Note. Every required field below is required whatever the status, a draft included: in 1.4.0 the plugin applies the full list to every status.

Request

POST https://your-site.example/wp-json/plugixa-recipe/v1/recipes

Request body

Content type: application/json

Field Type Required Description
title string Yes Plain text. Must not be blank.
description string Yes HTML; the tags allowed in post content are kept. Must contain some text.
image_id integer Yes Attachment id of the main image.
category_ids integer[] Yes At least one category id. Links the recipe to these categories, in this order.
difficulty string Yes easy, medium, hard or expert.
servings integer Yes At least 1.
prep_time integer Yes Minutes. 0 is accepted; empty is not.
cook_time integer Yes Minutes. 0 is accepted; empty is not.
ingredients object[] Yes At least one with a name. Fields as in Replace Ingredients.
instructions object[]|string[] Yes At least one step with text. Fields as in Replace Instructions; a bare string is a step.
status string No draft (the default), pending, published or archived, lower case exactly.
slug string No Made from the title when empty. Made unique by appending -2, -3, …
excerpt, notes, tips string No HTML, as description.
rest_time integer No Minutes.
servings_unit string No Defaults to servings.
yield_amount, yield_unit string No Free text, for example 12 and pancakes.
cost string No budget, moderate (the default), expensive or premium. The older low, medium and high are read as budget, moderate and expensive.
season string No spring, summer, autumn, winter, all, or empty.
cuisine_ids, course_ids integer[] No Links the recipe to these cuisines and courses.
gallery integer[] No Attachment ids of extra images.
tags string[] No Blanks and repeats are dropped.
equipment string[] No Equipment names. Or send equipment_items, a list of {name, link_url}, which wins when both are sent.
video_url, source_url string No URLs.
source, author_name string No Credit text.
is_featured, is_editor_pick integer No 1 or 0.
display_order integer No Manual position.
is_vegetarian, is_vegan, is_gluten_free, is_dairy_free, is_keto, is_low_carb, is_nut_free, is_paleo, is_sugar_free, is_halal, is_kosher integer No Diet flags, 1 or 0.
nutrition object No Stores a nutrition row. Fields as in Update Nutrition.
seo_title, seo_description, seo_keywords string No Plain text.
enable_schema boolean No Whether the recipe page carries structured data.
language_code, translation_group string No For multilingual sites.
custom_fields object No PRO Field key to value. Replaces every stored value. When sent, fields marked required must be filled.
page_layout string No PRO A layout name, or empty for the site default.

An ingredient’s quantity is also stored as numbers (amount, amount_max) when it reads as one: 2, 1 1/2, ½ or a range such as 2-3. A recipe created as published gets published_at set to now. total_time is worked out for you.

{
  "title": "Lemon Pancakes",
  "description": "<p>Light, fluffy pancakes with lemon zest.</p>",
  "image_id": 345,
  "category_ids": [
    3
  ],
  "course_ids": [
    8
  ],
  "difficulty": "easy",
  "cost": "budget",
  "servings": 4,
  "prep_time": 10,
  "cook_time": 15,
  "status": "published",
  "is_vegetarian": 1,
  "tags": [
    "breakfast",
    "brunch"
  ],
  "equipment": [
    "Frying pan"
  ],
  "ingredients": [
    {
      "quantity": "2",
      "unit": "cups",
      "name": "flour"
    },
    {
      "quantity": "1 1/2",
      "unit": "cups",
      "name": "milk",
      "substitution": "oat milk",
      "sort_order": 1
    }
  ],
  "instructions": [
    "Whisk the flour, milk and lemon zest.",
    {
      "instruction_text": "Cook each pancake for 2 minutes a side.",
      "timer_seconds": 240,
      "sort_order": 1
    }
  ]
}

Responses

200 OK. data is the new recipe, read back in full.

{
  "success": true,
  "message": "",
  "data": {
    "id": "12",
    "language_code": "",
    "translation_group": "",
    "title": "Lemon Pancakes",
    "slug": "lemon-pancakes",
    "description": "<p>Light, fluffy pancakes with lemon zest.</p>",
    "excerpt": "",
    "notes": "",
    "tips": "",
    "image_id": "345",
    "gallery": null,
    "tags": [
      "breakfast",
      "brunch"
    ],
    "equipment": [
      "Frying pan"
    ],
    "video_url": "",
    "servings": "4",
    "servings_unit": "servings",
    "yield_amount": "",
    "yield_unit": "",
    "prep_time": "10",
    "cook_time": "15",
    "rest_time": null,
    "total_time": "25",
    "difficulty": "easy",
    "cost": "budget",
    "season": "",
    "status": "published",
    "is_featured": "0",
    "is_editor_pick": "0",
    "display_order": "0",
    "source": "",
    "source_url": "",
    "author_name": "",
    "view_count": "0",
    "rating_average": "0.00",
    "rating_count": "0",
    "like_count": "0",
    "enable_schema": "1",
    "canonical_post_id": null,
    "seo_score": null,
    "seo_title": null,
    "seo_description": null,
    "seo_keywords": null,
    "focus_keyword": null,
    "is_vegetarian": "1",
    "is_vegan": "0",
    "is_gluten_free": "0",
    "is_dairy_free": "0",
    "is_keto": "0",
    "is_low_carb": "0",
    "is_nut_free": "0",
    "is_paleo": "0",
    "is_sugar_free": "0",
    "is_halal": "0",
    "is_kosher": "0",
    "published_at": "2026-11-12 09:30:00",
    "created_at": "2026-11-12 09:30:00",
    "created_by": "1",
    "submission_ip": null,
    "modified_at": null,
    "modified_by": null,
    "image_url": "https://your-site.example/wp-content/uploads/2026/11/lemon-pancakes-1024x683.jpg",
    "image_thumbnail": "https://your-site.example/wp-content/uploads/2026/11/lemon-pancakes-150x150.jpg",
    "equipment_items": [
      {
        "name": "Frying pan",
        "link_url": ""
      }
    ],
    "categories": [
      {
        "id": "3",
        "language_code": "",
        "translation_group": "",
        "name": "Breakfast",
        "slug": "breakfast",
        "description": "",
        "image_id": null,
        "display_order": "0",
        "created_at": "2026-11-01 08:00:00"
      }
    ],
    "cuisines": [],
    "courses": [
      {
        "id": "8",
        "name": "Breakfast",
        "slug": "breakfast",
        "description": null,
        "display_order": "7"
      }
    ],
    "category_id": 3,
    "category_ids": [
      3
    ],
    "cuisine_id": 0,
    "course_id": 8,
    "ingredients": [
      {
        "id": "101",
        "recipe_id": "12",
        "group_name": "",
        "group_order": "0",
        "sort_order": "0",
        "quantity": "2",
        "unit": "cups",
        "name": "flour",
        "notes": "",
        "link_url": "",
        "amount": "2.000",
        "amount_max": null,
        "is_optional": "0",
        "substitution": ""
      },
      {
        "id": "102",
        "recipe_id": "12",
        "group_name": "",
        "group_order": "0",
        "sort_order": "1",
        "quantity": "1 1/2",
        "unit": "cups",
        "name": "milk",
        "notes": "",
        "link_url": "",
        "amount": "1.500",
        "amount_max": null,
        "is_optional": "0",
        "substitution": "oat milk"
      }
    ],
    "instructions": [
      {
        "id": "201",
        "recipe_id": "12",
        "group_name": "",
        "group_order": "0",
        "sort_order": "0",
        "title": "",
        "instruction_text": "Whisk the flour, milk and lemon zest.",
        "image_id": null,
        "video_url": "",
        "duration": null,
        "timer_seconds": null,
        "tip": "",
        "text": "Whisk the flour, milk and lemon zest."
      },
      {
        "id": "202",
        "recipe_id": "12",
        "group_name": "",
        "group_order": "0",
        "sort_order": "1",
        "title": "",
        "instruction_text": "Cook each pancake for 2 minutes a side.",
        "image_id": null,
        "video_url": "",
        "duration": "4",
        "timer_seconds": "240",
        "tip": "",
        "text": "Cook each pancake for 2 minutes a side."
      }
    ],
    "nutrition": null
  }
}
Field Type Meaning
data.id string The recipe’s id, as a numeric string
data.status string draft, pending, published or archived
data.slug string Unique among recipes
data.prep_time, data.cook_time, data.rest_time string|null Minutes
data.total_time string Minutes: prep + cook + rest, worked out by the database
data.difficulty string easy, medium, hard or expert
data.cost string budget, moderate, expensive or premium
data.tags string[] Tags, decoded
data.equipment string[] Equipment names
data.equipment_items object[] The same equipment with each item’s optional link_url
data.gallery string|null The stored gallery, as JSON text. gallery_ids and gallery_urls are added when it is set
data.image_url, data.image_thumbnail string Only present when the recipe has an image
data.categories, data.cuisines, data.courses object[] The linked terms, every column
data.category_ids integer[] Ids of the linked categories
data.category_id, data.cuisine_id, data.course_id integer The first linked term of each kind, 0 when none
data.ingredients object[] In group order, then position. See List Ingredients
data.instructions object[] In group order, then position, each with a text copy of instruction_text
data.nutrition object|null The nutrition row, or null
data.published_at string|null Site-time datetime the recipe first went live
data.custom_fields object Pro, with Custom Fields on: field key to value
data.page_layout string Pro, with Recipe Layouts on: the recipe’s own layout, empty for the site default

The status is 200, not 201.

Errors

Status Code When
400 rest_error A required field is missing or empty. Checked in this order, and the first failure is reported: title, description, image, category, difficulty, servings, prep time, cook time, ingredient, instruction. data.errors names the field.
400 rest_error difficulty, cost, season or status is not one of the allowed values.
400 rest_error PRO A required custom field is empty, or page_layout names no layout.
403 rest_forbidden The request would publish the recipe or take it down, and you lack the publish capability.
500 rest_error The recipe row could not be written.

Plus the errors every endpoint can return.

Examples

curl -s -X POST "https://your-site.example/wp-json/plugixa-recipe/v1/recipes" \
  -u "admin:$WP_APP_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{"title":"Lemon Pancakes","description":"<p>Light, fluffy pancakes with lemon zest.</p>","image_id":345,"category_ids":[3],"difficulty":"easy","servings":4,"prep_time":10,"cook_time":15,"ingredients":[{"quantity":"2","unit":"cups","name":"flour"}],"instructions":["Whisk the flour, milk and lemon zest."]}'
<?php
$ch = curl_init('https://your-site.example/wp-json/plugixa-recipe/v1/recipes');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'admin:' . getenv('WP_APP_PASSWORD'),
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'title'        => 'Lemon Pancakes',
        'description'  => '<p>Light, fluffy pancakes with lemon zest.</p>',
        'image_id'     => 345,
        'category_ids' => [3],
        'difficulty'   => 'easy',
        'servings'     => 4,
        'prep_time'    => 10,
        'cook_time'    => 15,
        'ingredients'  => [
            [
                'quantity' => '2',
                'unit'     => 'cups',
                'name'     => 'flour',
            ],
        ],
        'instructions' => ['Whisk the flour, milk and lemon zest.'],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const auth = 'Basic ' + btoa(`admin:${process.env.WP_APP_PASSWORD}`);
const response = await fetch('https://your-site.example/wp-json/plugixa-recipe/v1/recipes', {
  method: 'POST',
  headers: {
    'Authorization': auth,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"title": "Lemon Pancakes", "description": "<p>Light, fluffy pancakes with lemon zest.</p>", "image_id": 345, "category_ids": [3], "difficulty": "easy", "servings": 4, "prep_time": 10, "cook_time": 15, "ingredients": [{"quantity": "2", "unit": "cups", "name": "flour"}], "instructions": ["Whisk the flour, milk and lemon zest."]}),
});
const { data } = await response.json();

Quick Links

Share