---
updatedAt: 2026-04-29T08:26:41.000Z
---

Fetch the complete documentation index at: https://apidocs.hibob.com/llms.txt. Use this file to discover all available pages before exploring further.

# Submit xAPI statement

Submits a single xAPI statement to record learner progress for a course. On success, returns `200 OK` with `accepted: true` and the echoed `statementId`.

Submitting the same statement `id` (UUID) more than once returns `409 Conflict`. Statements with an unrecognised verb are silently ignored and return `204 No Content` with no body.

**Before using this endpoint:**
<ul>
  <li>An active LMS integration must exist for the `provider-identifier` — create one using <a href="/reference/post_learning-lms-integrations" target="_blank">Create integration</a>.</li>
  <li>The `actor.mbox` email must match the work email of an active employee in Bob.</li>
  <li>The `object.id` should correspond to the `sourceLink` of a known training content item pushed via <a href="/reference/post_learning-lms-integrations-provider-identifier-training-content" target="_blank">Create training content</a>.</li>
  <li>Supply a unique `id` (UUID) per statement for idempotency — resubmitting the same UUID returns `409`.</li>
</ul>

**Testing notes:** Open the **Examples** panel and select a **Request Example** to inspect the body parameters. Supported xAPI verbs include `completed`, `passed`, and `failed`. The `result` object is optional but recommended.


# OpenAPI definition

```json
{
  "openapi": "3.1.1",
  "info": {
    "title": "Bob Learning API",
    "description": "Public API for partner Learning integrations: register an integration, push and update training content in bulk, archive content, and submit xAPI progress statements.",
    "license": {
      "name": "Proprietary",
      "url": "https://apidocs.hibob.com/docs/api-terms-of-use"
    },
    "contact": {
      "name": "Hi Bob, Inc."
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.hibob.com/v1",
      "description": "Production"
    },
    {
      "url": "https://api.sandbox.hibob.com/v1",
      "description": "Sandbox"
    }
  ],
  "x-readme": {
    "metrics-enabled": false
  },
  "tags": [
    {
      "name": "Provider integrations",
      "description": "Register and remove partner LMS integrations, manage training content, and submit xAPI progress statements"
    }
  ],
  "paths": {
    "/learning/lms-integrations/{provider-identifier}/xapi/statements": {
      "post": {
        "operationId": "post_learning-lms-integrations-provider-identifier-xapi-statements",
        "tags": [
          "Provider integrations"
        ],
        "summary": "Submit xAPI statement",
        "description": "Submits a single xAPI statement to record learner progress for a course. On success, returns `200 OK` with `accepted: true` and the echoed `statementId`.\n\nSubmitting the same statement `id` (UUID) more than once returns `409 Conflict`. Statements with an unrecognised verb are silently ignored and return `204 No Content` with no body.\n\n**Before using this endpoint:**\n<ul>\n  <li>An active LMS integration must exist for the `provider-identifier` — create one using <a href=\"/reference/post_learning-lms-integrations\" target=\"_blank\">Create integration</a>.</li>\n  <li>The `actor.mbox` email must match the work email of an active employee in Bob.</li>\n  <li>The `object.id` should correspond to the `sourceLink` of a known training content item pushed via <a href=\"/reference/post_learning-lms-integrations-provider-identifier-training-content\" target=\"_blank\">Create training content</a>.</li>\n  <li>Supply a unique `id` (UUID) per statement for idempotency — resubmitting the same UUID returns `409`.</li>\n</ul>\n\n**Testing notes:** Open the **Examples** panel and select a **Request Example** to inspect the body parameters. Supported xAPI verbs include `completed`, `passed`, and `failed`. The `result` object is optional but recommended.\n",
        "parameters": [
          {
            "name": "provider-identifier",
            "in": "path",
            "required": true,
            "description": "The provider identifier of the LMS integration.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/XapiProgressStatement"
              },
              "examples": {
                "completed": {
                  "summary": "Course completed",
                  "value": {
                    "id": "550e8400-e29b-41d4-a716-446655440000",
                    "actor": {
                      "mbox": "mailto:john.doe@acme.com",
                      "name": "John Doe"
                    },
                    "verb": {
                      "id": "http://adlnet.gov/expapi/verbs/completed",
                      "display": {
                        "en-US": "completed"
                      }
                    },
                    "object": {
                      "id": "https://provider.com/courses/course_123",
                      "definition": {
                        "name": {
                          "en-US": "Intro to Feedback"
                        }
                      }
                    },
                    "result": {
                      "completion": true,
                      "duration": "PT45M"
                    },
                    "timestamp": "2026-02-19T11:00:00Z"
                  }
                },
                "passed": {
                  "summary": "Course passed with score",
                  "value": {
                    "id": "661f9511-f30c-52e5-b827-557766551111",
                    "actor": {
                      "mbox": "mailto:jane.smith@acme.com",
                      "name": "Jane Smith"
                    },
                    "verb": {
                      "id": "http://adlnet.gov/expapi/verbs/passed",
                      "display": {
                        "en-US": "passed"
                      }
                    },
                    "object": {
                      "id": "https://provider.com/courses/course_456",
                      "definition": {
                        "name": {
                          "en-US": "Advanced Leadership"
                        }
                      }
                    },
                    "result": {
                      "completion": true,
                      "score": {
                        "scaled": 0.92
                      },
                      "duration": "PT1H20M"
                    },
                    "timestamp": "2026-02-20T09:30:00Z"
                  }
                },
                "attempted": {
                  "summary": "Course started (attempted)",
                  "value": {
                    "id": "772g0622-g41d-63f6-c938-668877662222",
                    "actor": {
                      "mbox": "mailto:alex.jones@acme.com",
                      "name": "Alex Jones"
                    },
                    "verb": {
                      "id": "http://adlnet.gov/expapi/verbs/attempted",
                      "display": {
                        "en-US": "attempted"
                      }
                    },
                    "object": {
                      "id": "https://provider.com/courses/course_123",
                      "definition": {
                        "name": {
                          "en-US": "Intro to Feedback"
                        }
                      }
                    },
                    "timestamp": "2026-02-20T10:00:00Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Statement accepted and processed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XapiStatementsResponse"
                },
                "examples": {
                  "withStatementId": {
                    "summary": "Statement accepted with statement ID echoed",
                    "value": {
                      "accepted": true,
                      "statementId": "550e8400-e29b-41d4-a716-446655440000"
                    }
                  },
                  "withoutStatementId": {
                    "summary": "Statement accepted without statement ID (no id in request)",
                    "value": {
                      "accepted": true,
                      "statementId": null
                    }
                  }
                }
              }
            }
          },
          "204": {
            "description": "No content — statement ignored (unknown type)"
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProgressErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProgressErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — feature disabled or missing permissions",
            "content": {}
          },
          "404": {
            "description": "Not found — employee or integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProgressErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict — duplicate statement id (idempotency)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XapiDuplicateStatementErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity — invalid xAPI statement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProgressErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "basic": []
          },
          {
            "Bearer": []
          }
        ],
        "x-internal": false
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basic": {
        "type": "http",
        "scheme": "basic",
        "description": "Basic HTTP authentication using service user credentials"
      },
      "Bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "OAuth 2.0",
        "description": "OAuth 2.0 access token. Complete the OAuth 2.0 flow in Postman, then paste the token here. <a href=\"https://apidocs.hibob.com/reference/oauth-20\" target=\"_blank\">Learn more about OAuth 2.0 in HiBob</a>"
      }
    },
    "schemas": {
      "ApiErrorResponse": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Error key identifier"
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "args": {
            "type": "array",
            "description": "Optional error arguments providing additional context",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "XapiStatementsResponse": {
        "type": "object",
        "description": "Successful xAPI ingest response (`XapiStatementsResponse`).",
        "properties": {
          "accepted": {
            "type": "boolean",
            "description": "Whether the statement was accepted."
          },
          "statementId": {
            "type": [
              "string",
              "null"
            ],
            "description": "Statement id echoed from the request when present."
          }
        }
      },
      "ProgressErrorResponse": {
        "type": "object",
        "description": "Structured error returned for several xAPI processing failures (`ProgressErrorResponse`).",
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine-readable error code (for example `VALIDATION_ERROR`)."
          },
          "message": {
            "type": "string",
            "description": "Human-readable message."
          },
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code for the error."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Time the error was produced."
          }
        }
      },
      "XapiDuplicateStatementErrorResponse": {
        "type": "object",
        "description": "Example contract for duplicate statement id (409). Align with your idempotency implementation.",
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine-readable error code for the duplicate statement.",
            "example": "DUPLICATE_EVENT"
          },
          "message": {
            "type": "string",
            "description": "Human-readable description of the duplicate statement error.",
            "example": "Statement id already processed"
          },
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code (409).",
            "example": 409
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Time the duplicate error was detected.",
            "example": "2026-02-19T11:00:05Z"
          }
        }
      },
      "XapiProgressStatement": {
        "type": "object",
        "description": "xAPI statement accepted by `XapiProgressStatement`. Unknown JSON fields may be ignored where annotated with `@JsonIgnoreProperties(ignoreUnknown = true)` on nested types.",
        "required": [
          "timestamp",
          "actor",
          "verb",
          "object"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Optional statement UUID."
          },
          "timestamp": {
            "type": "string",
            "description": "Statement timestamp (multiple ISO formats supported server-side)."
          },
          "actor": {
            "$ref": "#/components/schemas/XapiActor"
          },
          "verb": {
            "$ref": "#/components/schemas/XapiVerb"
          },
          "object": {
            "$ref": "#/components/schemas/XapiObject"
          },
          "result": {
            "$ref": "#/components/schemas/XapiResult"
          }
        }
      },
      "XapiActor": {
        "type": "object",
        "required": [
          "mbox"
        ],
        "properties": {
          "objectType": {
            "type": "string",
            "description": "Object type identifier for the actor, typically `Agent`."
          },
          "mbox": {
            "type": "string",
            "description": "Mailto IRI for the actor (for example `mailto:user@acme.com`)."
          },
          "name": {
            "type": "string",
            "description": "Display name of the actor."
          }
        }
      },
      "XapiVerb": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Verb IRI."
          },
          "display": {
            "type": "object",
            "description": "Language map (RFC 5646 language tags to display strings). Other locale keys may appear in payloads.",
            "properties": {
              "en-US": {
                "type": "string",
                "description": "Display string for the verb in `en-US`."
              }
            }
          }
        }
      },
      "XapiObject": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Activity id IRI."
          },
          "objectType": {
            "type": "string",
            "description": "Object type identifier, typically `Activity`."
          },
          "definition": {
            "$ref": "#/components/schemas/XapiObjectDefinition"
          }
        }
      },
      "XapiObjectDefinition": {
        "type": "object",
        "properties": {
          "name": {
            "type": "object",
            "description": "Language map for the activity name. Other locale keys may appear in payloads.",
            "properties": {
              "en-US": {
                "type": "string",
                "description": "Activity name in `en-US`."
              }
            }
          }
        }
      },
      "XapiResult": {
        "type": "object",
        "properties": {
          "completion": {
            "type": "boolean",
            "description": "Whether the activity was completed."
          },
          "score": {
            "type": "object",
            "description": "Score object (`XapiScore` — scaled value).",
            "properties": {
              "scaled": {
                "type": "number",
                "format": "double",
                "description": "Normalized score between -1 and 1 (decimal fraction)."
              }
            }
          },
          "extensions": {
            "type": "object",
            "description": "Optional extension map. Keys are typically IRIs; values are strings in the service model."
          },
          "duration": {
            "type": "string",
            "description": "ISO-8601 duration string (for example `PT45M`)."
          }
        }
      }
    }
  }
}
```