Webhooks

Webhooks notify and trigger custom code on your server via an HTTP API, called a webhook endpoint, when specific events occur in your ezeep Blue organization. Currently supported events include succeeded and failed print jobs.

Authorization

Our webhooks API requires OAuth2 tokens with scope:

Scope Description
webhooks read or modify resources with GET, POST, PATCH, DELETE, or PUT
webhooks.readonly read resources with GET

Topics

One webhook endpoint can be configured to receive events for multiple topics. Several endpoints can be associated with the same topic.

Topic Description
printjob_succeeded The print job was completed successfully.
printjob_failed The print job could not be completed successfully.

Add an endpoint

POST "https://api2.ezeep.com/webhooks/endpoints"
Attribute Type Required Description
authentication_scheme string no basic for Basic HTTP authentication (RFC 7617)
basic_password string no password for Basic HTTP authentication
basic_username string no username for Basic HTTP authentication
disabled boolean no true disables endpoint, false by default
name string yes human-readable name
topics string array no event topics
url string (uri) yes endpoint URL, must start with https://

Example request:

curl --request POST --url "https://api2.ezeep.com/webhooks/endpoints" \
  --header "Authorization: Bearer <access_token>" \
  --header "Content-Type: application/json" \
  --data '{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "disabled": false,
    "name": "My webhook",
    "topics": [
      "printjob_succeeded",
      "printjob_failed"
    ],
    "url": "https://example.com/webhook"
}'

Example response:

{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "disabled": false,
    "endpoint_id": "af47f7ec-0299-4267-b61b-736e887d6531",
    "name": "My webhook",
    "topics": [
        "printjob_succeeded",
        "printjob_failed"
    ],
    "url": "https://example.com/webhook"
}

Returned endpoint_id can be used to update, delete, or get an endpoint.

Update an endpoint

PATCH "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>"

Required header:

Content-Type: application/merge-patch+json

Uses JSON Merge Patch semantics.

Attribute Type Required Description
authentication_scheme string no basic for Basic HTTP authentication (RFC 7617), null for none
basic_password string no password for Basic HTTP authentication
basic_username string no username for Basic HTTP authentication
disabled boolean no true to disable endpoint, false to enable
name string no human-readable name
topics string array no event topics
url string (uri) no endpoint URL, must start with https://

Example request:

curl --request PATCH --url "https://api2.ezeep.com/webhooks/endpoints/af47f7ec-0299-4267-b61b-736e887d6531" \
  --header "Authorization: Bearer <access_token>" \
  --header "Content-Type: application/merge-patch+json" \
  --data '{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "name": "My webhook",
    "topics": [
        "printjob_succeeded",
        "printjob_failed"
    ],
    "url": "https://example.com/webhook"
}'

Example response:

{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "disabled": false,
    "endpoint_id": "af47f7ec-0299-4267-b61b-736e887d6531",
    "name": "My webhook",
    "topics": [
        "printjob_succeeded",
        "printjob_failed"
    ],
    "url": "https://example.com/webhook"
}

Delete an endpoint

DELETE "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>"

Example request:

curl --request DELETE --url "https://api2.ezeep.com/webhooks/endpoints/af47f7ec-0299-4267-b61b-736e887d6531" \
  --header "Authorization: Bearer <access_token>"

Get an endpoint

GET "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>"

Example request:

curl "https://api2.ezeep.com/webhooks/endpoints/af47f7ec-0299-4267-b61b-736e887d6531" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "disabled": false,
    "endpoint_id": "af47f7ec-0299-4267-b61b-736e887d6531",
    "name": "My webhook",
    "topics": [
        "printjob_succeeded",
        "printjob_failed"
    ],
    "url": "https://example.com/webhook"
}

List endpoints

GET "https://api2.ezeep.com/webhooks/endpoints"

Supports pagination.

Example request:

curl "https://api2.ezeep.com/webhooks/endpoints?limit=3" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
    "count": 4,
    "next": "https://api2.ezeep.com/webhooks/endpoints?limit=3&offset=3",
    "results": [
        {
            "authentication_scheme": "basic",
            "basic_password": "password",
            "basic_username": "username",
            "disabled": false,
            "endpoint_id": "3a98f4be-5bbf-487b-8fd6-1b5087c10457",
            "name": "All print jobs",
            "topics": [
                "printjob_failed",
                "printjob_succeeded"
            ],
            "url": "https://example.com/webhooks/printjobs"
        },
        {
            "authentication_scheme": "basic",
            "basic_password": "password",
            "basic_username": "username",
            "disabled": true,
            "endpoint_id": "83e07d88-9995-4036-9e6c-464fd29dc370",
            "name": "Failed print jobs",
            "topics": [
                "printjob_failed"
            ],
            "url": "https://example.com/webhooks/failed_printjobs"
        },
        {
            "disabled": true,
            "endpoint_id": "ab426e2b-f0e1-4366-996f-a4598870381d",
            "name": "Succeeded print jobs",
            "topics": [
                "printjob_succeeded"
            ],
            "url": "https://example.com/webhooks/succeeded_printjobs"
        }
    ]
}

Test an endpoint

Initiates an HTTP request from our server to the specified url with sample event content for the selected topic. No new endpoint will be added and any existing endpoints will remain unchanged.

PUT "https://api2.ezeep.com/webhooks/endpoints/test"
Attribute Type Required Description
authentication_scheme string no basic for Basic HTTP authentication (RFC 7617)
basic_password string no password for Basic HTTP authentication
basic_username string no username for Basic HTTP authentication
topic string yes event topic
url string (uri) yes endpoint URL, must start with https://

Example request:

curl --request PUT --url "https://api2.ezeep.com/webhooks/endpoints/test" \
  --header "Authorization: Bearer <access_token>" \
  --header "Content-Type: application/json" \
  --data '{
    "authentication_scheme": "basic",
    "basic_password": "password",
    "basic_username": "username",
    "topic": "printjob_succeeded",
    "url": "https://example.com/webhook"
}'

Example response:

{
    "request": {
        "body": "{\n  \"content\": {\n    \"printjob\": {\n      \"co2_impact\": 0,\n      \"color\": false,\n      \"connector_id\": \"d4ce3f24-a6a8-40d6-b55b-aed7ec46195a\",\n      \"connector_name\": \"Webhook test connector\",\n      \"copies\": 1,\n      \"created\": \"2023-07-24T20:15:23.4445326Z\",\n      \"duplex\": false,\n      \"filename\": \"Webhook test.ext\",\n      \"paper\": \"Letter\",\n      \"printer_id\": \"8f238b5e-bb12-4020-babc-c0ccd4d9d6a1\",\n      \"printer_name\": \"Webhook test printer\",\n      \"printjob_id\": \"707ffe75-d859-4e98-8748-3bd2f30e5f57\",\n      \"source\": \"Webhook test\",\n      \"status\": \"succeeded\",\n      \"total_printed_pages\": 0,\n      \"total_printed_sheets\": 0,\n      \"type\": \"network\",\n      \"user_billing_code\": \"Webhook test user billing code\",\n      \"user_email\": \"user@example.com\",\n      \"user_id\": \"9551a5ba-2933-4a67-a392-eea3687037ed\",\n      \"user_name\": \"Webhook test user\"\n    }\n  },\n  \"created\": \"2023-07-24T20:15:23.4802513Z\",\n  \"event_id\": \"8a9fb745-ad28-4e51-a4bc-2181588a2ce2\",\n  \"topic\": \"printjob_succeeded\"\n}",
        "headers": "Host: example.com\r\nAuthorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=\r\nUser-Agent: ezeep/2.0\r\nContent-Type: application/json; charset=utf-8\r\n",
        "start_line": "POST https://example.com/webhook HTTP/1.1"
    },
    "response": {
        "body": "",
        "headers": "Server: nginx\r\nDate: Mon, 24 Jul 2023 20:15:25 GMT\r\nContent-Type: text/plain; charset=UTF-8\r\n",
        "start_line": "HTTP/1.1 200 OK"
    },
    "status": "succeeded"
}

If response status is succeeded, then your endpoint has responded as expected.

In case of errors, status will be failed. In that case, error may be set to response_status_code to indicate an unexpected status code, or timeout if no response was received within 30 seconds. For requirements, refer to Implement an endpoint.

List failed endpoint events

Lists failed events along with the most recent attempt for the requested endpoint. Status pending indicates that another automated retry has been scheduled. On the other hand, status failed means that all automated retries have been exhausted, and you have the option to manually retry.

GET "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events"
Attribute Type Required Description
order string no comma-separated order, available values: created, -created, event_id, -event_id

Supports pagination.

Example request:

curl "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events?limit=3" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
  "count": 4,
  "next": "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events?limit=3&offset=3",
  "results": [
    {
      "created": "2023-09-26T12:24:22.008Z",
      "endpoint": {
        "error": "response_status_code",
        "last_attempt": "2023-09-26T12:24:22.008Z",
        "response_status_code": 500,
        "status": "pending"
      },
      "event_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "topic": "printjob_succeeded"
    },
    {
      "created": "2023-09-26T12:24:22.008Z",
      "endpoint": {
        "error": "response_status_code",
        "last_attempt": "2023-09-26T12:24:22.008Z",
        "response_status_code": 400,
        "status": "failed"
      },
      "event_id": "42bedf0d-5c36-4567-99da-40592892598d",
      "topic": "printjob_succeeded"
    },
    {
      "created": "2023-09-26T12:24:22.008Z",
      "endpoint": {
        "error": "timeout",
        "last_attempt": "2023-09-26T12:24:22.008Z",
        "status": "pending"
      },
      "event_id": "42bedf0d-5c36-4567-99da-40592892598d",
      "topic": "printjob_failed"
    }
  ]
}

Get a failed endpoint event

GET "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/<event_id>"

Example request:

curl "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
  "created": "2023-09-26T12:24:22.008Z",
  "endpoint": {
    "error": "response_status_code",
    "last_attempt": "2023-09-26T12:24:22.008Z",
    "response_status_code": 500,
    "status": "pending"
  },
  "event_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "topic": "printjob_succeeded"
}

Delete a failed endpoint event

DELETE "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/<event_id>"

Example request:

curl --request DELETE --url "https://api2.ezeep.com/webhooks/endpoints/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  --header "Authorization: Bearer <access_token>"

Delete all failed endpoint events

DELETE "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events"

Example request:

curl --request DELETE --url "https://api2.ezeep.com/webhooks/endpoints/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events" \
  --header "Authorization: Bearer <access_token>"

Retry a failed endpoint event

Retries a failed event synchronously.

Response status succeeded indicates that the retry was successful. In this case, the failed event has been deleted from our servers. It will not be included in future responses when listing events, and it will no longer be available for retry. Status failed indicates that your endpoint needs to be modified to meet our requirements. You can initiate another retry within 30 days of the first attempt.

PUT "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/<event_id>/retry"

Example request:

curl --request PUT --url "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/3fa85f64-5717-4562-b3fc-2c963f66afa6/retry" \
  --header "Authorization: Bearer <access_token>"

Example response if the retry was successful:

{
  "status": "succeeded"
}

Example response if your endpoint did not respond within our timeout of 30 seconds:

{
  "error": "timeout",
  "status": "failed"
}

Example response if your endpoint responded with an unexpected status code:

{
  "error": "response_status_code",
  "response_status_code": 500,
  "status": "failed"
}

Retry all failed endpoint events

Starts an operation to retry all failed events asynchronously. Only one operation of this kind can run at a time for a given endpoint. If a retry all operation is already in progress, any attempt to start a new one will be rejected with 409 Conflict.

The outcome of the retry all operation can be observed by listing failed events. Like individual retries, any event that succeeds will be deleted from our servers and will no longer be listed or available for further retries.

PUT "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/retry"

Example request:

curl --request PUT --url "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/retry" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
  "created": "2023-09-27T15:28:49.295Z"
}

Get retry all operation

Checks if a retry all operation is currently in progress for a given endpoint. If no such operation is in progress, including after a previously started one has completed, it returns 404 Not Found.

GET "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/retry"

Example request:

curl "https://api2.ezeep.com/webhooks/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  --header "Authorization: Bearer <access_token>"

Example responses:

{
  "created": "2023-09-27T15:28:49.295Z"
}

Cancel retry all operation

Cancels a retry all operation that was previously started for a given endpoint.

DELETE "https://api2.ezeep.com/webhooks/endpoints/<endpoint_id>/events/retry"

Example request:

curl --request DELETE --url "https://api2.ezeep.com/webhooks/endpoints/endpoints/41ab0833-3f23-431e-a2b5-bebf25ad8bcc/events/retry" \
  --header "Authorization: Bearer <access_token>"

Update data protection settings

These settings are applied to all webhook events sent to any endpoint in your ezeep Blue organization.

PATCH "https://api2.ezeep.com/webhooks/settings"

Required header:

Content-Type: application/merge-patch+json

Uses JSON Merge Patch semantics.

Attribute Type Required Description
file_name_obfuscated boolean no replace filename in webhook requests with random digits
user_email_disabled boolean no omit user_email from webhook requests
user_name_disabled boolean no omit user_name from webhook requests

Example request:

curl --request PATCH --url "https://api2.ezeep.com/webhooks/settings" \
   --header "Authorization: Bearer <access_token>" \
   --header "Content-Type: application/merge-patch+json" \
   --data '{
     "file_name_obfuscated": true,
     "user_email_disabled": true,
     "user_name_disabled": true
}'

Example response:

{
    "file_name_obfuscated": true,
    "user_email_disabled": true,
    "user_name_disabled": true
}

Get data protection settings

GET "https://api2.ezeep.com/webhooks/settings"

Example request:

curl --url "https://api2.ezeep.com/webhooks/settings" \
  --header "Authorization: Bearer <access_token>"

Example response:

{
    "file_name_obfuscated": false,
    "user_email_disabled": false,
    "user_name_disabled": false
}

By default, all boolean values are false.

Implement an endpoint

Your endpoint must use HTTPS and accept POST requests.

Example request line and headers as sent by our server:

POST "https://example.com/webhook" HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: example.com
User-Agent: ezeep/2.0

For endpoints with authentication_scheme set to basic and at least one of basic_username or basic_password present, an Authorization header will be sent according to RFC 7617, for example:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Request content:

Attribute Type Required Description
content object no topic-dependent, see below
created string (date-time) yes time when event was created
event_id string (uuid) yes unique ID for each event
topic string yes printjob_failed or printjob_succeeded

content when topic is printjob_failed or printjob_succeeded:

Attribute Type Required Description
printjob object yes final state of print job, see below

printjob contains:

Attribute Type Required Description
co2_impact integer no CO₂ impact in g
color boolean no chromaticity: true for color, false for black/white
connector_id string (uuid) no identifier of target connector, required when type is network
connector_name string no name of target connector, required when connector_id is present
copies integer no number of printed copies
created string (date-time) yes time when print job was created
duplex boolean no true for duplex, false for simplex
filename string no filename with extension
paper string no name of paper format
printer_id string (uuid) no identifier of target printer, required when type is network
printer_name string no name of printer, required when printer_id is present
printjob_id string (uuid) yes unique identifier for print job
source string no origin of print job
status string yes failed or succeeded, matching topic
total_printed_pages integer no number of printed pages, including copies
total_printed_sheets integer no number of printed sheets, including copies
type string yes network, additional values may be added in the future
user_billing_code string no billing code of user
user_email string no email address of user
user_id string (uuid) no identifier of user, required when type is network
user_name string no display name of user

Example request content:

{
  "content": {
    "printjob": {
      "co2_impact": 5,
      "color": false,
      "connector_id": "17f75aef-8214-4826-a7af-981a40078e0f",
      "connector_name": "Webhook test connector",
      "copies": 1,
      "created": "2023-07-24T17:33:26.0630285Z",
      "duplex": false,
      "filename": "Webhook test.ext",
      "paper": "Letter",
      "printer_id": "62b3dcb2-8a96-45d6-8863-7817ae4aa9a3",
      "printer_name": "Webhook test printer",
      "printjob_id": "6b9e29d4-21ec-4b9b-b867-64ce167c35ea",
      "source": "Webhook test",
      "status": "succeeded",
      "total_printed_pages": 1,
      "total_printed_sheets": 1,
      "type": "network",
      "user_billing_code": "Webhook test user billing code",
      "user_email": "user@example.com",
      "user_id": "3222ca07-ea89-44e4-a56c-04a2a0fa9604",
      "user_name": "Webhook test user"
    }
  },
  "created": "2023-07-24T17:33:26.2090852Z",
  "event_id": "87c4a7d5-d88e-4acb-8b5f-3dc5a520f0c8",
  "topic": "printjob_succeeded"
}

Your endpoint must respond with a 2xx status code, such as 200 OK. The response must be sent within 30 seconds. We recommend to defer time-consuming operations, such as requests against other APIs. Any response content will be ignored.

Failed events

Any endpoint response that takes longer than 30 seconds or is sent with a non-2xx HTTP status code will be considered a failed event. These failed events are stored on our servers for 30 days. Our servers automatically retry failed events for a period of three days, using exponential backoff. Additionally, you have the option to list failed events, and manually trigger a retry for selected or all events.