xAPI actor session
const url = 'https://example.com/wp-json/wp2lms/turbo/v1/xapi-actor/session';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"email":"learner@example.com","name":"Anna Ivanova"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/wp-json/wp2lms/turbo/v1/xapi-actor/session \ --header 'Content-Type: application/json' \ --data '{ "email": "learner@example.com", "name": "Anna Ivanova" }'Public same-origin bridge from an xAPI actor to a WordPress cookie session. PHP finds the user by email or creates a learner (UserProvisioner: role wp2lms_learner if that role exists, otherwise subscriber), then wp_set_current_user + wp_set_auth_cookie and a fresh wp_rest nonce.
email is required (sanitize_email + is_email, otherwise 400 invalid_email). name is optional, default empty string; if the user already exists and name is non-empty, display_name is updated.
This is not an administrator login: roles administrator/editor/author or capabilities edit_posts / manage_options — 403 privileged_user. The bridge must be enabled (platform module xapi_actor_session or filter wp2turbo/xapi/enable_actor_session), otherwise 403 disabled. A wp_rest nonce is required in X-WP-Nonce or _wpnonce (otherwise 403 invalid_nonce). An editor cookie session is not required.
Request Bodyrequired
Section titled “Request Bodyrequired”object
XAPI actor email. Required. PHP: sanitize_email; empty/invalid — 400 invalid_email. Used as the lookup/create key for the WP user.
Learner display name. Optional, default ‘’. On create, empty name falls back to a login derived from the email local part. For an existing user, a non-empty name updates display_name.
Example
{ "email": "learner@example.com", "name": "Anna Ivanova"}Responses
Section titled “Responses”Learner session established. Body: ok, created, user (id/email/display_name), wp_rest nonce.
object
PHP always true on HTTP 200 of this bridge.
True if wp_insert_user just created the learner; false if a user with this email already existed.
Learner the cookie session was set for. Not a guest and not null.
object
WordPress user ID.
User_email (or the original email if get_userdata failed).
User display_name.
Fresh wp_create_nonce(‘wp_rest’) after the session is set — for follow-up cookie requests.
Example
{ "ok": true, "created": false, "user": { "id": 45, "email": "learner@example.com", "display_name": "Anna Ivanova" }, "nonce": "a1b2c3d4e5"}Invalid_email — empty or invalid email after sanitize_email.
object
Machine-readable WP_Error code (for example wp2lms_static_builder_busy, rest_forbidden, invalid_nonce).
Human-readable error message from PHP / WordPress REST.
Usually { status: <HTTP code> }. If status is missing, core REST often returns 500.
object
Example
{ "code": "wp2lms_static_builder_busy", "message": "Build is currently building and cannot be updated.", "data": { "status": 409 }}Disabled — bridge is off; invalid_nonce — missing/invalid wp_rest nonce; privileged_user — the email belongs to a privileged account.
object
Machine-readable WP_Error code (for example wp2lms_static_builder_busy, rest_forbidden, invalid_nonce).
Human-readable error message from PHP / WordPress REST.
Usually { status: <HTTP code> }. If status is missing, core REST often returns 500.
object
Example
{ "code": "wp2lms_static_builder_busy", "message": "Build is currently building and cannot be updated.", "data": { "status": 409 }}WP_Error from wp_insert_user with no HTTP status in data (often existing_user_login / existing_user_email). WordPress REST surfaces those as 500.
object
Machine-readable WP_Error code (for example wp2lms_static_builder_busy, rest_forbidden, invalid_nonce).
Human-readable error message from PHP / WordPress REST.
Usually { status: <HTTP code> }. If status is missing, core REST often returns 500.
object
Example
{ "code": "wp2lms_static_builder_busy", "message": "Build is currently building and cannot be updated.", "data": { "status": 409 }}