---
updatedAt: 2026-08-05T09:55:14.000Z
---

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

# Update skills

Bulk-update API-origin skills resolved by source + externalId locator.

**Testing notes:**

1. Use the testing widget's **Try It!** option to test this endpoint.
2. Use the **Examples > Request Example** option to see how to initiate body parameters. Copy the example into an external tool if needed.

**Error handling:**

This endpoint always returns HTTP **200** when the request is accepted, even if some items in the `items` array fail.

* Inspect the `results` array for every item — do not assume all skills were updated because the top-level call returned 200.
* Each result includes `index` (matching the request item), `status` (`succeeded` or `failed`), `httpStatus`, and either a `resource` or an `errors` array.
* Items are resolved only by `/skill/source` + `/skill/externalId`. Locators that point to Bob-created (non-API-origin) skills are reported as not found.
* Common per-item failures include missing locator fields, no writable field provided, skill not found, and unknown proficiency level IDs.
* Retry only after correcting the failed items. Successful items in the same request are already updated.

# OpenAPI definition

```json
{
  "openapi": "3.1.1",
  "info": {
    "title": "Skills API",
    "contact": {
      "name": "Hi Bob, Inc."
    },
    "description": "Public API for managing a company's API-origin skills in the Bob skills framework.\n\nUse this API to search, create, update, and archive skills that are owned by an\nexternal system (identified by the mandatory `/skill/source` + `/skill/externalId`\nlocator), and to discover the company's proficiency levels. All write payloads use\nthe flattened `fieldId: value` object contract.",
    "license": {
      "name": "Proprietary",
      "url": "https://apidocs.hibob.com/docs/api-terms-of-use"
    },
    "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": "Skills",
      "description": "Manage a company's API-origin skills and read its proficiency levels."
    }
  ],
  "security": [
    {
      "basic": []
    },
    {
      "bearer": []
    }
  ],
  "paths": {
    "/skills": {
      "patch": {
        "operationId": "patch_skills",
        "tags": [
          "Skills"
        ],
        "summary": "Update skills",
        "description": "Bulk-update API-origin skills resolved by source + externalId locator.",
        "x-readme": {
          "hidden": true
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSkillsInput"
              },
              "examples": {
                "updateCategoryAndLevels": {
                  "summary": "Update category, status, and replace proficiency levels",
                  "value": {
                    "items": [
                      {
                        "/skill/source": "sharepoint",
                        "/skill/externalId": "SP-SKILL-002",
                        "/skill/categoryName": "Analytics",
                        "/skill/status": "active",
                        "/skill/proficiencyLevels": [
                          {
                            "proficiencyLevelId": 1425,
                            "description": "Explains core analytics concepts with support."
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateSkillsOutput"
                },
                "examples": {
                  "mixedOutcome": {
                    "summary": "One updated, one missing writable field",
                    "value": {
                      "results": [
                        {
                          "index": 0,
                          "status": "succeeded",
                          "httpStatus": 200,
                          "resource": {
                            "/skill/id": 12345,
                            "/skill/source": "sharepoint",
                            "/skill/externalId": "SP-SKILL-002"
                          }
                        },
                        {
                          "index": 1,
                          "status": "failed",
                          "httpStatus": 422,
                          "errors": [
                            {
                              "code": "VALIDATION_ERROR",
                              "message": "At least one writable field is required."
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request — malformed request, unsupported field or filter, or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — authentication credentials are missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — the caller lacks the required Skills permission or OAuth scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — per-tenant rate limit exceeded. Retry after the indicated delay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error — an unexpected error occurred on the server.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          }
        },
        "x-internal": false
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basic": {
        "type": "http",
        "scheme": "basic"
      },
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "OAuth 2.0",
        "description": "OAuth 2.0 authentication using an Access Token is available for\nregistered partners only. Try It! does not support the full HiBob OAuth\nflow. You can follow <a href=\"https://apidocs.hibob.com/reference/oauth-20\"\ntarget=\"_blank\" rel=\"noopener noreferrer\">these steps</a> to complete the\nOAuth 2.0 flow in Postman and then paste the token here."
      }
    },
    "schemas": {
      "ApiErrorResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "details": {
            "type": "object",
            "additionalProperties": true,
            "description": "Structured error context keyed by field or domain identifier"
          },
          "request_id": {
            "type": "string",
            "description": "Request identifier for support and tracing"
          }
        }
      },
      "ProficiencyLevelAssignment": {
        "description": "A single proficiency-level entry attached to a skill. When `/skill/proficiencyLevels`\nis supplied on create or update, the full array replaces the skill's existing\nproficiency-level content.",
        "type": "object",
        "properties": {
          "proficiencyLevelId": {
            "type": "integer",
            "format": "int64",
            "description": "Numeric ID of an existing company proficiency level. Discover valid IDs with\n`GET /v1/skills/proficiency-levels`."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1000,
            "description": "Description of what this skill looks like at that proficiency level. Up to 1000 characters."
          }
        },
        "required": [
          "proficiencyLevelId"
        ]
      },
      "SkillBulkItemError": {
        "description": "Per-item error returned inside a bulk write result.",
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable error code (for example `VALIDATION_ERROR`,\n`DUPLICATE_EXTERNAL_LOCATOR`, `DUPLICATE_SKILL_NAME`, `SKILL_NOT_FOUND`)."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation of the failure for this item."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "SkillBulkItemResult": {
        "description": "Outcome of a single item in a bulk create, update, or archive request.",
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "Zero-based index of the item in the request `items` array."
          },
          "status": {
            "type": "string",
            "description": "`succeeded` or `failed`."
          },
          "httpStatus": {
            "type": "integer",
            "description": "Per-item HTTP-style status (for example `201` created, `200` updated,\n`404` not found, `409` conflict, `422` unprocessable)."
          },
          "resource": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SkillWriteResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Locator + ID of the affected skill. Present when `status` is `succeeded`."
          },
          "errors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/SkillBulkItemError"
            },
            "description": "Errors describing why the item failed. Present when `status` is `failed`."
          }
        },
        "required": [
          "index",
          "status",
          "httpStatus"
        ]
      },
      "SkillStatus": {
        "description": "Lifecycle status of a skill.",
        "type": "string",
        "enum": [
          "draft",
          "active",
          "inactive"
        ]
      },
      "SkillUpdateItem": {
        "description": "A skill to update, resolved by its `/skill/source` + `/skill/externalId` locator.\nOnly fields present in the item are changed.",
        "type": "object",
        "properties": {
          "/skill/source": {
            "type": "string",
            "description": "External source system that owns this skill. Required — part of the locator."
          },
          "/skill/externalId": {
            "type": "string",
            "description": "External ID of the skill in the source system. Required — part of the locator."
          },
          "/skill/name": {
            "type": [
              "string",
              "null"
            ],
            "description": "New skill display name."
          },
          "/skill/description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1000,
            "description": "New free-text description (up to 1000 characters)."
          },
          "/skill/categoryName": {
            "type": [
              "string",
              "null"
            ],
            "description": "New category display name. Must reference an existing category."
          },
          "/skill/status": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SkillStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "New lifecycle status."
          },
          "/skill/proficiencyLevels": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ProficiencyLevelAssignment"
            },
            "description": "Full replacement of the skill's proficiency-level content. Omit to leave\nexisting content unchanged; send an empty array to remove all content."
          }
        },
        "required": [
          "/skill/source",
          "/skill/externalId"
        ]
      },
      "SkillWriteResult": {
        "description": "Locator + identity returned for a successfully written skill.",
        "type": "object",
        "properties": {
          "/skill/id": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Bob skill ID of the created or updated skill."
          },
          "/skill/source": {
            "type": [
              "string",
              "null"
            ],
            "description": "External source system that owns this skill (echoed from the request locator)."
          },
          "/skill/externalId": {
            "type": [
              "string",
              "null"
            ],
            "description": "External ID of the skill in the source system (echoed from the request locator)."
          }
        }
      },
      "UpdateSkillsInput": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SkillUpdateItem"
            },
            "minItems": 1,
            "maxItems": 100,
            "description": "Skills to update (1–100 items)."
          }
        },
        "required": [
          "items"
        ],
        "default": {
          "items": [
            {
              "source": "sharepoint",
              "externalId": "SP-SKILL-002",
              "categoryName": "Analytics",
              "status": "active",
              "proficiencyLevels": [
                {
                  "proficiencyLevelId": 1425,
                  "description": "Explains core analytics concepts with support."
                }
              ]
            }
          ]
        }
      },
      "UpdateSkillsOutput": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SkillBulkItemResult"
            },
            "description": "Per-item outcomes, in request order."
          }
        },
        "required": [
          "results"
        ]
      }
    }
  }
}
```