---
updatedAt: 2026-04-29T08:25:50.000Z
---

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

# Create training content (bulk insert)

Creates one or more training content items for the integration in a single request (up to 500 items per call).

Each item requires a unique `/trainingContent/externalIdentifier` and a `/trainingContent/title`. All other fields are optional. If the same `externalIdentifier` appears more than once in a request, only the last occurrence is used.

Returns `200 OK` with a `success` array of processed identifiers and an `errors` array for any items that failed. Returns `403` with no body if the LMS feature is disabled for the company.

**Before using this endpoint:**
<ul>
  <li>Create an integration first using <a href="/reference/post_learning-lms-integrations" target="_blank">Create integration</a> — the `provider-identifier` path parameter must match an active integration.</li>
  <li>Each item must include `/trainingContent/externalIdentifier` (unique per provider) and `/trainingContent/title`. All other fields are optional.</li>
  <li>The `externalIdentifier` is your stable, idempotency key for the content row — use the same value to update or archive the item later.</li>
</ul>

**Testing notes:** Open the **Examples** panel and select a **Request Example** to inspect the body parameters. The response body contains a `success` array of processed identifiers and an `errors` array for any failures.


# 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}/training-content": {
      "post": {
        "operationId": "post_learning-lms-integrations-provider-identifier-training-content",
        "tags": [
          "Provider integrations"
        ],
        "summary": "Create training content (bulk insert)",
        "description": "Creates one or more training content items for the integration in a single request (up to 500 items per call).\n\nEach item requires a unique `/trainingContent/externalIdentifier` and a `/trainingContent/title`. All other fields are optional. If the same `externalIdentifier` appears more than once in a request, only the last occurrence is used.\n\nReturns `200 OK` with a `success` array of processed identifiers and an `errors` array for any items that failed. Returns `403` with no body if the LMS feature is disabled for the company.\n\n**Before using this endpoint:**\n<ul>\n  <li>Create an integration first using <a href=\"/reference/post_learning-lms-integrations\" target=\"_blank\">Create integration</a> — the `provider-identifier` path parameter must match an active integration.</li>\n  <li>Each item must include `/trainingContent/externalIdentifier` (unique per provider) and `/trainingContent/title`. All other fields are optional.</li>\n  <li>The `externalIdentifier` is your stable, idempotency key for the content row — use the same value to update or archive the item later.</li>\n</ul>\n\n**Testing notes:** Open the **Examples** panel and select a **Request Example** to inspect the body parameters. The response body contains a `success` array of processed identifiers and an `errors` array for any failures.\n",
        "parameters": [
          {
            "name": "provider-identifier",
            "in": "path",
            "required": true,
            "description": "The provider identifier of the LMS integration (same value used when creating the integration).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerContentBulkWriteRequest"
              },
              "examples": {
                "fullExample": {
                  "summary": "Two courses with all fields",
                  "value": {
                    "items": [
                      {
                        "/trainingContent/externalIdentifier": "ACME-course-001",
                        "/trainingContent/title": "Introduction to Safety",
                        "/trainingContent/description": "Overview of workplace safety practices.",
                        "/trainingContent/sourceLink": "https://acme.com/courses/001",
                        "/trainingContent/thumbnail": "https://acme.com/img/001.png",
                        "/trainingContent/duration": 3600,
                        "/trainingContent/language": "en",
                        "/trainingContent/category": "Compliance",
                        "/trainingContent/learningGoals": "Understand key safety concepts.",
                        "/trainingContent/publishDate": "2025-03-01T12:00:00Z",
                        "/trainingContent/intendedFor": "All employees"
                      },
                      {
                        "/trainingContent/externalIdentifier": "ACME-course-002",
                        "/trainingContent/title": "Advanced Leadership",
                        "/trainingContent/sourceLink": "https://acme.com/courses/002",
                        "/trainingContent/language": "en"
                      }
                    ]
                  }
                },
                "minimalExample": {
                  "summary": "Minimal required fields only",
                  "description": "Only externalIdentifier and title are required per item.",
                  "value": {
                    "items": [
                      {
                        "/trainingContent/externalIdentifier": "ACME-course-010",
                        "/trainingContent/title": "Onboarding Essentials"
                      },
                      {
                        "/trainingContent/externalIdentifier": "ACME-course-011",
                        "/trainingContent/title": "Data Privacy Fundamentals"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success — processing result with per-item successes and failures",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerContentBulkResponse"
                },
                "examples": {
                  "allSuccess": {
                    "summary": "All items created successfully",
                    "value": {
                      "success": [
                        "ACME-course-010",
                        "ACME-course-011"
                      ],
                      "errors": []
                    }
                  },
                  "partialSuccess": {
                    "summary": "Mixed success and errors",
                    "value": {
                      "success": [
                        "ACME-course-001",
                        "ACME-course-002"
                      ],
                      "errors": [
                        {
                          "externalIdentifier": "ACME-course-009",
                          "message": "Already exists"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request — for example batch size exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — feature disabled or missing permissions",
            "content": {}
          },
          "404": {
            "description": "Not found — unknown integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity — invalid item(s)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        },
        "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"
            }
          }
        }
      },
      "PartnerContentBulkWriteRequest": {
        "type": "object",
        "description": "Bulk training content write request. Each element of `items` is a JSON object whose keys are field IDs under `/trainingContent/`.",
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "description": "Content rows. Maximum count is enforced by the service (default 500).",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/TrainingContentItemFields"
            }
          }
        }
      },
      "TrainingContentItemFields": {
        "type": "object",
        "description": "One training content row. Use `/trainingContent/externalIdentifier` and `/trainingContent/title` for create; both are required and non-blank after mapping. Optional fields mirror `PartnerContent` in the service.",
        "properties": {
          "/trainingContent/externalIdentifier": {
            "type": "string",
            "description": "External idempotency key for the content row."
          },
          "/trainingContent/title": {
            "type": "string",
            "description": "Title of the training content."
          },
          "/trainingContent/description": {
            "type": "string",
            "description": "Description text."
          },
          "/trainingContent/sourceLink": {
            "type": "string",
            "description": "URL to the content at the provider."
          },
          "/trainingContent/thumbnail": {
            "type": "string",
            "description": "Thumbnail image URL."
          },
          "/trainingContent/duration": {
            "type": "integer",
            "description": "Duration in seconds."
          },
          "/trainingContent/language": {
            "type": "string",
            "description": "Language code for the training content. To obtain the available language codes, call the <a href=\"https://apidocs.hibob.com/reference/get_company-named-lists-listname\" target=\"_blank\">Get all company lists Metadata API</a> with `languages` in the listname path parameter."
          },
          "/trainingContent/category": {
            "type": "string",
            "description": "Optional. The category label (display name) to assign to the training content. If the name matches an existing entry in the Bob's categories list, that category is used.  If no match is found, a new category is created automatically. To view existing categories, call the <a href=\"https://apidocs.hibob.com/reference/get_company-named-lists-listname\" target=\"_blank\">Get all company lists Metadata API</a> with `trainingContentCategories` in the listname path parameter."
          },
          "/trainingContent/learningGoals": {
            "type": "string",
            "description": "Learning goals or outcomes text."
          },
          "/trainingContent/publishDate": {
            "type": "string",
            "description": "Publish date-time (ISO-8601 string as accepted by the mapper)."
          },
          "/trainingContent/createdAt": {
            "type": "string",
            "description": "The time the content was last updated on the provider's side (ISO-8601 date-time string). Used for delta sync scenarios to determine whether a content item has changed since the last sync."
          },
          "/trainingContent/intendedFor": {
            "type": "string",
            "description": "Free-text description of the intended audience (for example, \"All employees\" or \"Managers\")."
          }
        }
      },
      "PartnerContentBulkResponse": {
        "type": "object",
        "description": "Bulk operation outcome from `PartnerContentBulkResponse`.",
        "properties": {
          "success": {
            "type": "array",
            "description": "External identifiers that were processed successfully.",
            "items": {
              "type": "string"
            }
          },
          "errors": {
            "type": "array",
            "description": "Per-item failures with external id and message.",
            "items": {
              "$ref": "#/components/schemas/PartnerContentErrorItem"
            }
          }
        }
      },
      "PartnerContentErrorItem": {
        "type": "object",
        "required": [
          "externalIdentifier",
          "message"
        ],
        "properties": {
          "externalIdentifier": {
            "type": "string",
            "description": "External identifier of the failing item."
          },
          "message": {
            "type": "string",
            "description": "Failure reason (for example validation or downstream error)."
          }
        }
      }
    }
  }
}
```