Skip to content

Batch assembly / ingest

POST
/wp-json/wp2lms-pro/embed-packages/v1/batch
curl --request POST \
--url 'https://example.com/wp-json/wp2lms-pro/embed-packages/v1/batch?blog_id=1' \
--header 'Content-Type: application/json' \
--header 'X-WP-Nonce: <X-WP-Nonce>' \
--data '{ "package": { "title": "HTML course", "files": { "index.html": "<!doctype html><html lang=\"en\"><title>Start</title><h1>Start</h1></html>", "module-2.html": "<!doctype html><html lang=\"en\"><title>Module 2</title><h1>Module 2</h1></html>" } }, "pages": [ { "title": "Start", "launch_path": "index.html", "slug": "start", "page_status": "publish" }, { "title": "Module 2", "launch_path": "module-2.html", "slug": "module-2" } ], "link_replace": true, "page_status": "publish", "alpine": false }'

Creates package(s), optionally WordPress pages and bindings, in one request (BatchAssembler::run). This is not a single POST /packages and not Static Builder itself. Two modes. If a package object is sent — one package for all: tree package.files / package.html (html → index.html when the tree has no index.html/Index.html), then either pages[] (new or existing WP pages with per-page launch_path) or materialize_all (same as materialize-pages). Empty package.title → “HTML package”. Package status is always publish. When package is present, items is ignored. Otherwise a non-empty items[] is required (else 400 embed_packages_batch_empty): one package per item. create_pages defaults to true; link_replace defaults to true in both modes. Empty item title → “HTML {n}”. Truthy build.run tries to start AgentBuild; a module failure does not fail HTTP — the message goes to warnings[], the response is still 201. Requires manage_network (multisite) or edit_pages. Cookie + X-WP-Nonce or Application Password.

blog_id
integer
>= 1

Network site ID (switch_to_blog). Optional: defaults to the request current blog. Not a package id and not page_id. Minimum 1; on a single site it must match the current site — otherwise 400 embed_packages_invalid_blog. In a network an unknown site or a site from another network is 404 embed_packages_unknown_blog.

Example
1
Media typeapplication/json
object
package
object
title

Title of the shared package. Optional; empty → “HTML package”. Post status is always publish.

string
html

HTML that PHP puts into files[‘index.html’] when the tree does not already have index.html/Index.html.

string
files

Map of relative paths to contents. Keys must be safe relative paths (PackageFilePolicy). An empty object is not treated as a tree. Unsafe path — unsafe_path; disallowed extension — disallowed_extension.

object
key
additional properties
One of:

Raw file text (HTML/CSS/JS).

string
pages

WordPress pages in shared-package mode (objects, not numbers). If empty and materialize_all — materialize the package index.

Array<object>
object
title

WordPress page title. Empty → launch_path basename or “Page {n}”.

string
launch_path

Relative HTML in the shared package for this page (sanitized like PagePackageReplace). Not page_id.

string
page_status

Status of this page. Optional; else body.page_status, else publish.

string
Allowed values: publish draft private
slug

post_name. Optional; else sanitize of the launch_path basename.

string
page_id

ID of an existing WordPress page (post_type=page) for wp_update_post instead of insert. Not the package id. 0 or not-a-page → a new page is created.

integer
alpine

Alpine on this page when link_replace is on. Default false.

boolean
items

One-package-per-item mode. Ignored when a package object is sent. Empty array without package — 400 embed_packages_batch_empty.

Array<object>
object
title

Package title (and page title if create_pages). Empty → “HTML {n}”.

string
html

HTML placed in files[‘index.html’] if that key is not already set.

string
files

Map of relative paths to contents. Keys must be safe relative paths (PackageFilePolicy). An empty object is not treated as a tree. Unsafe path — unsafe_path; disallowed extension — disallowed_extension.

object
key
additional properties
One of:

Raw file text (HTML/CSS/JS).

string
alpine

Alpine when binding the created/updated page. Default false.

boolean
launch_path

Launch override on the WordPress page. Empty → launch_path from package meta.

string
page_status

WordPress page status if create_pages. Default publish.

string
Allowed values: publish draft private
slug

WordPress page post_name if create_pages.

string
page_id

Existing WordPress page ID for update instead of insert. Not the package id.

integer
materialize_all

Package mode only: if pages is empty/missing, call PagesMaterializer. Default false.

boolean
create_pages

Items mode only: create/update WordPress pages. Optional, default true.

boolean
link_replace

Immediately PagePackageReplace::save on created pages. Optional, default true.

boolean
page_status

Default page status (materialize_all and pages[] without their own page_status). Default publish.

string
Allowed values: publish draft private
alpine

Alpine for materialize_all in package mode. Default false. pages[]/items[] have their own alpine.

boolean
build
object
run

If truthy — after ingest call AgentBuild (BuildService::create + run). A module failure does not change the HTTP status; the text goes to warnings[].

boolean
page_ids

Extra WordPress page IDs in addition to those the batch created. Not package ids.

Array<integer>
title

Build course_name. Optional, default “Agent embed batch”.

string
api_type

Build api_type. Optional, default local (sanitize_key).

string
export_mode

Build export_mode. Optional, default package.

string
main_page_id

WordPress main page ID for AgentBuild, if the key is sent.

integer
course_id

String course_id for the build, if the key is sent.

string
version

Build version ((float)), if the key is sent.

number
sync

Second argument of BuildService::run($id, $sync). Default false.

boolean
Example
{
"package": {
"title": "HTML course",
"files": {
"index.html": "<!doctype html><html lang=\"en\"><title>Start</title><h1>Start</h1></html>",
"module-2.html": "<!doctype html><html lang=\"en\"><title>Module 2</title><h1>Module 2</h1></html>"
}
},
"pages": [
{
"title": "Start",
"launch_path": "index.html",
"slug": "start",
"page_status": "publish"
},
{
"title": "Module 2",
"launch_path": "module-2.html",
"slug": "module-2"
}
],
"link_replace": true,
"page_status": "publish",
"alpine": false
}

Ingest completed. package mode — package_id, meta, launch_url, pages[], is_multipage. items mode — items[]. Always blog_id; optionally build and warnings.

Media typeapplication/json

Shape depends on the mode. package — package_id, meta, launch_url, pages, is_multipage. items — items[]. RestApi always adds blog_id. build — only if build.run succeeded without WP_Error; otherwise the text is in warnings.

object
package_id

Shared package ID (package mode). Absent in items mode.

integer
meta

Full post meta array _wp2lms_embed_package (PackageMeta::get). Empty object when the package has not been ingested.

object
content_type

Type after ManifestPipeline — web, scorm1.2, scorm2004, or xapi. Empty until content is uploaded.

string
version

Version from the manifest (for SCORM often the same as content_type). Empty string for typical web packages.

string
activity_id

XAPI activity id. If the parser omitted it — {home}wp2lms-embed-package/{id}.

string
launch_path

Relative launch HTML inside storage (from the manifest or fallback index.html).

string
title

Title from launch HTML / manifest; PHP may overwrite the package post_title with this value.

string
mastery_score

Mastery score from imsmanifest (SCORM), otherwise null.

number
nullable
content_tool

Authoring-tool detector: ispring, articulate_rise, articulate_storyline, articulate_presenter, captivate, elucidat, or an empty string.

string
storage_rel

Path from uploads basedir, wp2lms-embed-packages/{id}/.

string
uploaded_at

Unix time of the last successful content write (time() in finalize).

integer
is_multipage

True only for content_type=web with no content_tool and ≥2 HTML files in the index.

boolean
pages

HTML index (path+title) when the package is multipage; otherwise [].

Array<object>
object
path

Relative HTML path inside the package directory (posix, no leading /). From PackagePagesIndex::scan.

string
title

Title from the file <title> tag, or the basename if the tag is missing.

string
launch_url

Launch URL of the shared package (package mode).

string format: uri
pages

WordPress pages in package mode (not the same as meta.pages inside the package).

Array<object>
object
package_id

ID of the created shared package.

integer
page_id

WordPress page ID (created or updated). Not the package id.

integer
title

Page title as written in the batch.

string
slug

Slug sent to post_name (may be empty if omitted and not derived from launch_path).

string
launch_path

Page launch path (override or package default).

string
is_multipage

Copy of is_multipage of the shared package (package mode).

boolean
items

Items[] mode results (one package per item).

Array<object>
object
package_id

Package ID created for this items[] entry.

integer
page_id

WordPress page ID, or null when create_pages=false.

integer
nullable
title

Item title (package/page).

string
launch_path

Override or launch_path from package meta.

string
launch_url

Absolute launch URL of this package.

string format: uri
meta

Full post meta array _wp2lms_embed_package (PackageMeta::get). Empty object when the package has not been ingested.

object
content_type

Type after ManifestPipeline — web, scorm1.2, scorm2004, or xapi. Empty until content is uploaded.

string
version

Version from the manifest (for SCORM often the same as content_type). Empty string for typical web packages.

string
activity_id

XAPI activity id. If the parser omitted it — {home}wp2lms-embed-package/{id}.

string
launch_path

Relative launch HTML inside storage (from the manifest or fallback index.html).

string
title

Title from launch HTML / manifest; PHP may overwrite the package post_title with this value.

string
mastery_score

Mastery score from imsmanifest (SCORM), otherwise null.

number
nullable
content_tool

Authoring-tool detector: ispring, articulate_rise, articulate_storyline, articulate_presenter, captivate, elucidat, or an empty string.

string
storage_rel

Path from uploads basedir, wp2lms-embed-packages/{id}/.

string
uploaded_at

Unix time of the last successful content write (time() in finalize).

integer
is_multipage

True only for content_type=web with no content_tool and ≥2 HTML files in the index.

boolean
pages

HTML index (path+title) when the package is multipage; otherwise [].

Array<object>
object
path

Relative HTML path inside the package directory (posix, no leading /). From PackagePagesIndex::scan.

string
title

Title from the file <title> tag, or the basename if the tag is missing.

string
blog_id

Site ID after switch. RestApi always appends it.

integer
build

AgentBuild wrapper { created, run } when build.run is truthy and the module did not return WP_Error. Otherwise the field is absent.

object
key
additional properties
any
warnings

Messages (e.g. AgentBuild unavailable). Do not change HTTP 201.

Array<string>
Example
{
"package_id": 42,
"meta": {
"content_type": "web",
"version": "",
"activity_id": "https://lms.example.com/wp2lms-embed-package/42",
"launch_path": "index.html",
"title": "HTML course",
"mastery_score": null,
"content_tool": "",
"storage_rel": "wp2lms-embed-packages/42/",
"uploaded_at": 1726252800,
"is_multipage": true,
"pages": [
{
"path": "index.html",
"title": "Start"
},
{
"path": "module-2.html",
"title": "Module 2"
}
]
},
"launch_url": "https://lms.example.com/wp-content/uploads/wp2lms-embed-packages/42/index.html",
"pages": [
{
"package_id": 42,
"page_id": 128,
"title": "Start",
"slug": "start",
"launch_path": "index.html"
},
{
"package_id": 42,
"page_id": 129,
"title": "Module 2",
"slug": "module-2",
"launch_path": "module-2.html"
}
],
"is_multipage": true,
"blog_id": 1
}

Embed_packages_batch_empty — no package object and empty items[]; embed_packages_batch_package — package is not an object; embed_packages_batch_page — pages[n] is not an object; embed_packages_batch_item — items[n] is not an object; embed_packages_invalid_blog — invalid blog_id.

Media typeapplication/json
object
code

WP_Error code (get_error_code()), e.g. embed_packages_not_found.

string
message

WP_Error text (get_error_message()).

string
data

WP_Error data. Usually { "status": 404 }. Ingest/materialize errors without status are returned by WordPress REST as 500.

object
Example
{
"code": "embed_packages_not_found",
"message": "Package not found.",
"data": {
"status": 404
}
}

Not authenticated. WordPress REST: rest_forbidden (status 401) when there is no cookie session. Cookie + X-WP-Nonce or Application Password.

Media typeapplication/json
object
code

WP_Error code (get_error_code()), e.g. embed_packages_not_found.

string
message

WP_Error text (get_error_message()).

string
data

WP_Error data. Usually { "status": 404 }. Ingest/materialize errors without status are returned by WordPress REST as 500.

object
Example
{
"code": "embed_packages_not_found",
"message": "Package not found.",
"data": {
"status": 404
}
}

Missing manage_network (multisite) or edit_pages (single site), or invalid REST nonce (rest_cookie_invalid_nonce).

Media typeapplication/json
object
code

WP_Error code (get_error_code()), e.g. embed_packages_not_found.

string
message

WP_Error text (get_error_message()).

string
data

WP_Error data. Usually { "status": 404 }. Ingest/materialize errors without status are returned by WordPress REST as 500.

object
Example
{
"code": "embed_packages_not_found",
"message": "Package not found.",
"data": {
"status": 404
}
}

Embed_packages_unknown_blog — that site does not exist in the network, or it belongs to another network.

Media typeapplication/json
object
code

WP_Error code (get_error_code()), e.g. embed_packages_not_found.

string
message

WP_Error text (get_error_message()).

string
data

WP_Error data. Usually { "status": 404 }. Ingest/materialize errors without status are returned by WordPress REST as 500.

object
Example
{
"code": "embed_packages_not_found",
"message": "Package not found.",
"data": {
"status": 404
}
}

WP_Error with no HTTP status — wp_insert_post/wp_update_post or tree ingest failure (empty_tree, unsafe_path, disallowed_extension, process_failed, write_failed, and similar). WordPress REST surfaces those as 500.

Media typeapplication/json
object
code

WP_Error code (get_error_code()), e.g. embed_packages_not_found.

string
message

WP_Error text (get_error_message()).

string
data

WP_Error data. Usually { "status": 404 }. Ingest/materialize errors without status are returned by WordPress REST as 500.

object
Example
{
"code": "embed_packages_not_found",
"message": "Package not found.",
"data": {
"status": 404
}
}