# Create new webhook. Create a new webhook. This endpoint requires the `personio:webhooks:write` scope. # OpenAPI definition ```json { "openapi": "3.0.3", "info": { "title": "Webhooks Management API", "version": "2.0.0", "description": "Endpoints to manage webhooks." }, "servers": [ { "url": "https://api.personio.de" } ], "security": [ { "BearerAuth": [] } ], "paths": { "/v2/webhooks": { "post": { "summary": "Create new webhook.", "description": "Create a new webhook. This endpoint requires the `personio:webhooks:write` scope.", "tags": [ "Webhooks" ], "parameters": [], "requestBody": { "$ref": "#/components/requestBodies/CreateWebhookRequest" }, "responses": { "201": { "$ref": "#/components/responses/WebhookCreatedResponse" }, "400": { "$ref": "#/components/responses/WebhookBadRequestErrorResponse" }, "401": { "$ref": "#/components/responses/WebhookInvalidAuthenticationErrorResponse" }, "403": { "$ref": "#/components/responses/CreationAccessForbiddenErrorResponse" }, "409": { "$ref": "#/components/responses/WebhookConflictErrorResponse" }, "422": { "$ref": "#/components/responses/WebhookUnprocessableEntityErrorResponse" } } } } }, "components": { "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer" } }, "schemas": { "Webhook": { "description": "Webhook schema", "type": "object", "required": [ "id", "url", "description" ], "properties": { "id": { "type": "string", "format": "uuid", "description": "The identifier for the webhook.", "readOnly": true }, "url": { "type": "string", "format": "url", "description": "The url that should be called once a webhook event is fired. This should be an HTTPS endpoint." }, "description": { "type": "string", "description": "The description of the webhook configuration." }, "token": { "type": "string", "description": "The token used to authenticate the request on the webhook's URL. The callback will include this exact value in the Authorization header for authentication. If a specific format is required (e.g., \"Bearer\" or \"Basic\"), please include the desired prefix (such as \"Bearer \" or \"Basic \") at the beginning of the token when configuring it, as no prefix will be added automatically." }, "status": { "$ref": "#/components/schemas/WebhookStatus" }, "enabled_events": { "type": "array", "items": { "type": "string" }, "description": "Contains the list of enabled events." }, "created_at": { "type": "string", "format": "date-time", "description": "The timestamp of when the webhook was created in UTC.", "readOnly": true }, "updated_at": { "type": "string", "format": "date-time", "description": "The timestamp of when the webhook was last updated in UTC. Carries an initial value of created_at.", "readOnly": true }, "auth_type": { "type": "string", "description": "The authentication type used for webhook delivery requests.\n- NONE: No authentication headers will be sent.\n- TOKEN: (default) A static token will be sent in the Authorization header.\n- CUSTOM: Up to 3 custom HTTP headers will be sent as specified in `custom_headers`.\n", "enum": [ "NONE", "TOKEN", "CUSTOM" ], "default": "TOKEN" }, "custom_headers": { "type": "object", "additionalProperties": { "type": "string", "description": "Header value" }, "description": "A map of custom HTTP headers to include in webhook delivery requests.\nOnly allowed if `auth_type` is `CUSTOM`.\n- Maximum of 3 headers (map entries).\n- Header names (keys) must not match or start with any of the following (case-insensitive):\n host, content-length, transfer-encoding, connection, upgrade, te, trailer, expect, content-type\n- Example:\n {\n \"X-My-Auth\": \"abc123\",\n \"X-Tracking\": \"track-me\"\n }\n" } } }, "WebhookStatus": { "type": "string", "enum": [ "ENABLED", "DISABLED" ], "description": "The status of the webhook configuration." }, "CreateWebhookRequest": { "description": "Create Webhook request schema.\n- If `auth_type` is null or `TOKEN`, `token` is required.\n- If `auth_type` is `CUSTOM`, `custom_headers` is required and `token` is ignored.\n- If `auth_type` is `NONE`, neither `token` nor `custom_headers` are required.\n", "type": "object", "required": [ "url", "description", "enabled_events" ], "properties": { "url": { "$ref": "#/components/schemas/Webhook/properties/url" }, "description": { "$ref": "#/components/schemas/Webhook/properties/description" }, "status": { "allOf": [ { "$ref": "#/components/schemas/WebhookStatus" }, { "default": "DISABLED" } ] }, "auth_type": { "$ref": "#/components/schemas/Webhook/properties/auth_type" }, "token": { "$ref": "#/components/schemas/Webhook/properties/token" }, "custom_headers": { "$ref": "#/components/schemas/Webhook/properties/custom_headers" }, "enabled_events": { "$ref": "#/components/schemas/Webhook/properties/enabled_events" } } } }, "requestBodies": { "CreateWebhookRequest": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequest" }, "examples": { "Valid request": { "$ref": "#/components/examples/ValidCreateWebhookRequestPayload" }, "Valid request (No Auth)": { "$ref": "#/components/examples/ValidCreateWebhookRequestNoAuthPayload" }, "Valid request (Custom Auth)": { "$ref": "#/components/examples/ValidCreateWebhookRequestCustomAuthPayload" }, "Missing required parameters": { "$ref": "#/components/examples/InvalidMissingRequiredParametersCreateWebhookRequestPayload" }, "Invalid URL": { "$ref": "#/components/examples/InvalidUrlCreateWebhookRequestPayload" }, "Invalid JSON": { "value": { "random": "YOLO" } }, "Duplicate URL": { "$ref": "#/components/examples/ValidCreateWebhookRequestPayload" }, "Invalid Hostname": { "$ref": "#/components/examples/InvalidHostnameWebhookRequestPayload" } } } } } }, "responses": { "WebhooksResponse": { "description": "Successful list all webhooks response.", "content": { "application/json": { "schema": { "type": "object", "properties": { "_data": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } }, "_meta": { "description": "This object represents the metadata information for an object. It's a set of arbitrary key/value attributes such as `links`.", "type": "object", "readOnly": true, "properties": { "links": { "type": "object", "additionalProperties": { "description": "This objects represents a hyperlink.", "type": "object", "readOnly": true, "properties": { "href": { "type": "string", "format": "uri" } }, "additionalProperties": true }, "example": { "links": { "self": { "href": "https://api.personio.de/v2/person?cursor=" } } } } } } } }, "examples": { "List all webhooks": { "$ref": "#/components/examples/ListAllWebhooksResponse" }, "List all webhooks where enabled_events contains person.updated": { "$ref": "#/components/examples/ListAllWebhooksEnabledEventFilterResponse" }, "List all webhooks where status is enabled": { "$ref": "#/components/examples/ListAllWebhooksStatusFilterResponse" } } } } }, "WebhookCreatedResponse": { "description": "The webhook was successfully created.", "content": { "application/json": { "schema": { "description": "This is an object that is returned whenever a new resource is created. It contains the unique identifier for the created resource and optionally a link that can be used to retrieve it.", "properties": { "id": { "readOnly": true, "type": "string", "example": "some-random-id", "description": "The id of the created resource." }, "_meta": { "$ref": "#/components/responses/WebhooksResponse/content/application~1json/schema/properties/_meta" } } }, "examples": { "Valid request": { "$ref": "#/components/examples/WebhookCreatedResponse" }, "Valid request (No Auth)": { "$ref": "#/components/examples/WebhookCreatedResponse" }, "Valid request (Custom Auth)": { "$ref": "#/components/examples/WebhookCreatedResponse" } } } } }, "WebhookBadRequestErrorResponse": { "description": "The webhook could not be created due to faulty input payload.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/responses/WebhookTestEventBadRequest/content/application~1problem%2Bjson/schema" }, "examples": { "Invalid JSON": { "$ref": "#/components/examples/InvalidPostPayloadResponse" }, "Invalid status field": { "$ref": "#/components/examples/InvalidStatusPayloadResponse" }, "Missing required parameters": { "$ref": "#/components/examples/MissingRequiredFieldsPayloadResponse" } } } } }, "CreationAccessForbiddenErrorResponse": { "description": "Forbidden to create webhooks.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/responses/WebhookTestEventBadRequest/content/application~1problem%2Bjson/schema" }, "examples": { "Access Forbidden": { "$ref": "#/components/examples/WebhookAccessForbiddenErrorResponse" }, "Webhooks Configuration Limit Reached": { "$ref": "#/components/examples/WebhooksLimitReachedErrorResponse" } } } } }, "WebhookInvalidAuthenticationErrorResponse": { "description": "The webhook could not be created due to invalid authentication.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/responses/WebhookTestEventBadRequest/content/application~1problem%2Bjson/schema" }, "examples": { "Invalid authentication type": { "$ref": "#/components/examples/InvalidAuthenticationPayloadResponse" } } } } }, "WebhookUnprocessableEntityErrorResponse": { "description": "The webhook could not be created due to semantically incorrect input payload.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/responses/WebhookTestEventBadRequest/content/application~1problem%2Bjson/schema" }, "examples": { "Invalid URL": { "$ref": "#/components/examples/InvalidUrlPayloadResponse" }, "Invalid Hostname": { "$ref": "#/components/examples/InvalidHostnamePayloadResponse" } } } } }, "WebhookConflictErrorResponse": { "description": "The webhook could not be created due to a failed precondition.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/responses/WebhookTestEventBadRequest/content/application~1problem%2Bjson/schema" }, "examples": { "Duplicate URL": { "$ref": "#/components/examples/ConflictPayloadResponse" } } } } }, "WebhookTestEventBadRequest": { "description": "Bad request - invalid event name, event not enabled, or missing required payload data.", "content": { "application/problem+json": { "schema": { "type": "object", "description": "This object represents an error response.", "properties": { "personio_trace_id": { "type": "string", "example": "aswo3f-a202lfso-312123sld-1230ddd", "description": "A unique ID that was created for this error." }, "timestamp": { "type": "string", "format": "date-time", "example": "2021-05-28T11:17:30.000Z", "description": "The timestamp of when the error occurred." }, "errors": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string", "example": "Not found", "description": "The title of the error." }, "detail": { "type": "string", "example": "The requested resource was not found.", "description": "A short description about the error." }, "type": { "type": "string", "format": "uri", "example": "https://developer.personio.de/reference/errors#common.requested_resource_not_found", "description": "A link to the developer hub where more information can be found for the encountered error." }, "_meta": { "type": "object", "additionalProperties": { "type": "string" } } } } } } }, "examples": { "400 missing required payload data": { "$ref": "#/components/examples/TestEventMissingPayloadDataResponse" } } } } } }, "examples": { "ValidCreateWebhookRequestPayload": { "value": { "url": "https://example.com/callback", "description": "Sample webhook", "status": "ENABLED", "token": "eyJraWQiOiAnJYjE1NzEyZC00YzFmLTUxODEtYWExNC03MjdlZmViNmYw", "enabled_events": [ "person.updated" ] } }, "ValidCreateWebhookRequestNoAuthPayload": { "value": { "url": "https://example.com/noauth", "description": "Sample webhook with no authentication", "status": "ENABLED", "auth_type": "NONE", "enabled_events": [ "person.updated" ] } }, "ValidCreateWebhookRequestCustomAuthPayload": { "value": { "url": "https://example.com/customauth", "description": "Sample webhook with custom headers", "status": "ENABLED", "auth_type": "CUSTOM", "custom_headers": { "X-My-Auth": "abc123", "X-Tracking": "track-me" }, "enabled_events": [ "person.updated" ] } }, "InvalidMissingRequiredParametersCreateWebhookRequestPayload": { "value": { "description": "Sample webhook", "status": "ENABLED", "enabled_events": [ "person.updated" ] } }, "InvalidUrlCreateWebhookRequestPayload": { "value": { "url": "http://example.com/callback", "description": "Sample webhook", "status": "ENABLED", "token": "eyJraWQiOiAnJYjE1NzEyZC00YzFmLTUxODEtYWExNC03MjdlZmViNmYw", "enabled_events": [ "person.updated" ] } }, "InvalidHostnameWebhookRequestPayload": { "value": { "url": "https://10.1.1.1/callback", "description": "Sample webhook", "token": "eyJraWQiOiAnJYjE1NzEyZC00YzFmLTUxODEtYWExNC03MjdlZmViNmYw", "enabled_events": [ "person.updated" ] } }, "WebhookCreatedResponse": { "value": { "id": "2e4324b0-1b0e-11ee-a7f7-e37ffd9b3a44" } }, "WebhookAccessForbiddenErrorResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Access denied", "detail": "Access denied to perform webhook operations" } ] } }, "WebhooksLimitReachedErrorResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Webhooks Limit reached for company", "detail": "The company has reached the webhooks limit of 50" } ] } }, "InvalidStatusPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Input must be a valid JSON", "detail": "Invalid value for field: status. Supported values are [ENABLED, DISABLED]" } ] } }, "InvalidPostPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Input must be valid JSON", "detail": "The provided input is not a JSON object." } ] } }, "MissingRequiredFieldsPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Missing required fields", "detail": "The following required fields are missing: [url]", "_meta": { "field": "url" } } ] } }, "InvalidUrlPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "The URL is considered invalid.", "detail": "URL does not use HTTPS scheme." } ] } }, "InvalidHostnamePayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "The URL is considered invalid.", "detail": "Hostname does not resolve to a valid address." } ] } }, "ConflictPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Duplicate URL", "detail": "Another webhook configuration with identical URL exists.", "_meta": { "id": "89821e24-1b15-11ee-8f8e-430f660e2f9e" } } ] } }, "InvalidAuthenticationPayloadResponse": { "value": { "personio_trace_id": "aswo3f-a202lfso-312123sld-1230ddd", "timestamp": "2021-05-28T11:17:30Z", "errors": [ { "title": "Invalid authentication", "detail": "The authentication type is unsupported." } ] } } } } } ```