Select programming language for code examples

linkWebhooks

Webhook events are dispatched using POST requests to an account's webhook endpoints. Events usually get sent quickly, but sometimes there can be a small delay. If you experience a delay longer than 1 hour for the initial event, please contact us.

Webhooks are asynchronous events. We do our best to always send them in a timely manner, but we DO NOT recommend relying on webhooks for events that are time-sensitive e.g., waiting on a webhook to finish processing a web request.

To verify that a webhook event originated from us, you can verify its cryptographic signature. Alternatively, you can retrieve the event via the API.

linkEvent Types

The following events are dispatched to all endpoints with a POST request containing an event object.

NOTE: Events that occur on "sub" resources like account.plan do not trigger the parent's update event. In addition, resource deletion e.g. policy.deleted or user.deleted events will not trigger "cascading" deletion events on dependent associations.
Event Trigger Payload
account.billing.updated When your account's billing is updated The updated billing object
account.plan.updated When your account's plan is updated The updated plan object
account.subscription.canceled When your account's subscription is canceled The updated account object
account.subscription.paused When your account's subscription is paused The updated account object
account.subscription.renewed When your account's subscription is renewed The updated account object
account.subscription.resumed When your account's subscription is resumed The updated account object
account.updated When your account is updated The updated account object
artifact.created When an artifact is created The created artifact object
artifact.deleted When an artifact is deleted The deleted artifact object
artifact.downloaded When an artifact is downloaded The artifact object
artifact.updated When an artifact is updated The updated artifact object
artifact.uploaded When an artifact is uploaded The artifact object
component.created When a component is created The new component object
component.deleted When a component is deleted The deleted component object
component.updated When a component is updated The updated component object
entitlement.created When an entitlement is created The entitlement object
entitlement.deleted When an entitlement is deleted The deleted entitlement object
entitlement.updated When an entitlement is updated The updated entitlement object
group.created When a group is created The group object
group.deleted When a group is deleted The deleted group object
group.owners.attached When owners are attached to a group The attached owner objects
group.owners.detached When owners are detached from a group The detached owner objects
group.updated When a group is updated The updated group object
license.check-in-overdue When a license is overdue for check-in The overdue license object
license.check-in-required-soon When a license requires a check-in within the next 3 days
Note: Up to 1 event will be sent every day until overdue
The license object
license.checked-in When a license is checked in The checked in license object
license.checked-out When a license is checked out The license file object
license.created When a license is created The license object
license.deleted When a license is deleted The deleted license object
license.entitlements.attached When entitlements are attached to a license The attached entitlement objects
license.entitlements.detached When entitlements are detached from a license The detached entitlement objects
license.expired When a license has expired The expired license object
license.expiring-soon When a license is expiring within the next 3 days
Note: Up to 1 event will be sent every day until expiration
The expiring license object
license.group.updated When a license's group relationship is changed The license object
license.policy.updated When a license's policy relationship has been changed The license object
license.reinstated When a license is reinstated The reinstated license object
license.renewed When a license is renewed The renewed license object
license.revoked When a license is revoked The revoked license object
license.suspended When a license is suspended The suspended license object
license.updated When a license is updated The updated license object
license.usage.decremented When a license's usage is decremented The used license object
license.usage.incremented When a license's usage is incremented The used license object
license.usage.reset When a license's usage is reset The reset license object
license.user.updated When a license's user relationship has been changed The license object
license.validation.failed When a license validation fails The validated license object
license.validation.succeeded When a license validation succeeds The validated license object
machine.checked-out When a machine is checked out The machine file object
machine.created When a machine is created The machine object
machine.deleted When a machine is deleted The deleted machine object
machine.group.updated When a machine's group relationship is changed The machine object
machine.heartbeat.dead When a machine heartbeat monitor determines the machine is dead (i.e. it received no ping within the heartbeat window) The dead machine object
machine.heartbeat.ping When a machine heartbeat ping is received The pinged machine object
machine.heartbeat.reset When a machine heartbeat is reset The reset machine object
machine.heartbeat.resurrected When a dead machine heartbeat is resurrected The resurrected machine object
machine.updated When a machine is updated The updated machine object
package.created When a package is created The package object
package.deleted When a package is deleted The deleted package object
package.updated When a package is updated The updated package object
policy.created When a policy is created The policy object
policy.deleted When a policy is deleted The deleted policy object
policy.entitlements.attached When entitlements are attached to a policy The attached entitlement objects
policy.entitlements.detached When entitlements are detached from a policy The detached entitlement objects
policy.pool.popped When a key is popped from a pool The popped key object
policy.updated When a policy is updated The updated policy object
process.created When a process is created The new process object
process.deleted When a process is deleted The deleted process object
process.heartbeat.dead When a process heartbeat monitor determines the process is dead (i.e. it received no ping within the heartbeat window) The dead process object
process.heartbeat.ping When a process heartbeat ping is received The pinged process object
process.heartbeat.resurrected When a dead machine heartbeat is resurrected The resurrected process object
process.updated When a process is updated The updated process object
product.created When a product is created The product object
product.deleted When a product is deleted The deleted product object
product.updated When a product is updated The updated product object
release.constraints.attached When constraints are attached to a release The attached constraint objects
release.constraints.detached When constraints are detached from a release The detached constraint objects
release.created When a release is created The created release object
release.deleted When a release is deleted The deleted release object
release.package.updated When a release's package is updated The updated release object
release.published When a release is published The release object
release.updated When a release is updated The updated release object
release.upgraded When a release is upgraded The release object
release.yanked When a release is yanked The release object
second-factor.created When a second factor is created The second factor object
second-factor.deleted When a second factor is deleted The deleted second factor object
second-factor.disabled When a second factor is disabled The disabled second factor object
second-factor.enabled When a second factor is enabled The enabled second factor object
token.generated When a token is generated The generated token object
token.regenerated When a token is regenerated The regenerated token object
token.revoked When a token is revoked The revoked token object
user.banned When a user is banned The user object
user.created When a user is created The user object
user.deleted When a user is deleted The deleted user object
user.group.updated When a user's group relationship is changed The user object
user.password-reset When a user requests a password reset The user object and reset token
user.unbanned When a user is unbanned The user object
user.updated When a user is updated The updated user object

Example webhook handler using Node and Express

const bodyParser = require("body-parser")
const express = require("express")
const app = express()
 
app.use(bodyParser.json({ type: "application/vnd.api+json" }))
app.use(bodyParser.json({ type: "application/json" }))
 
app.post("/my/webhook/url", async (req, res) => {
const { data } = req.body
if (!data) {
return res.sendStatus(400)
}
 
// TODO: Verify webhook's signature (https://keygen.sh/docs/api/signatures/)
 
switch (data.attributes.event) {
case "user.password-reset":
const reset = JSON.parse(data.attributes.payload)
const { passwordResetToken } = reset.meta
 
// … email the password reset token to the user for fulfillment
 
break
case "user.created":
const user = JSON.parse(data.attributes.payload)
 
// … do something when a user is created e.g. create a Stripe customer
 
break
case "license.created":
const license = JSON.parse(data.attributes.payload)
 
// … do something when a license is created e.g. charge a user
 
break
}
 
// Let Keygen know the event was received successfully
res.sendStatus(200)
})
 
const server = app.listen(8080, 'localhost', () => {
const { address, port } = server.address()
 
console.log(`Listening at http://${address}:${port}`)
})

linkThe endpoint object

Below you will find the various attributes for the endpoint resource, as well as the endpoint resource's relationships.

When delivering webhook events to your endpoint, an event is considered failed if the endpoint responds with a non-2xx status code. It will automatically be retried with an exponential backoff. We will perform 15 retries over approximately 3 days.

linkAttributes

  • linkdata.attributes.url

    string

    The url that events are dispatched to. Must use the https protocol. Must have a valid SSL certificate. You may include a username and password in the URL, e.g. https://user:[email protected]/webhooks.

  • linkdata.attributes.signatureAlgorithm

    stringdefault=ed25519

    The signature algorithm for the webhook endpoint. Must be one of: ed25519, rsa-pss-sha256, or rsa-sha256.

  • linkdata.attributes.subscriptions

    array<string>default=["*"]

    The event types the webhook endpoint subscribes to.

  • linkdata.attributes.created

    timestamp (iso8601)read only

    When the endpoint was created.

  • linkdata.attributes.updated

    timestamp (iso8601)read only

    When the endpoint was last updated.

linkRelationships

  • linkdata.relationships.account

    individual

    The account that the endpoint belongs to.

  • linkdata.relationships.environment

    individualent onlyThese relationships are only available for accounts on an Ent tier.

    The environment that the endpoint belongs to.

Example object

{
"data": {
"id": "0ed7330f-8d2c-405e-88b6-0a4a327e620c",
"type": "webhook-endpoints",
"links": {
"self": "/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c"
},
"attributes": {
"url": "https://api.example.com/v1/keygen",
"subscriptions": [
"*"
],
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkCreate an endpoint

Creates a new endpoint for the account.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

linkAttributes

  • linkdata.attributes.url

    stringrequired

    The url that events are dispatched to. Must use the https protocol. Must have a valid SSL certificate. You may include a username and password in the URL, e.g. https://user:[email protected]/webhooks.

  • linkdata.attributes.subscriptions

    array<string>optional

    The event types this webhook endpoint subscribes to. See event types for all options. Use * to listen for all event types.

linkReturns

A 201 Created response will be returned along with the new webhook endpoint object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints", {
method: "POST",
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
body: JSON.stringify({
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v1/keygen"
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
},
data=json.dumps({
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v1/keygen"
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints",
method: .post,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
],
parameters: [
"data": [
"type": "webhook-endpoints",
"attributes": [
"url": "https://api.example.com/v1/keygen"
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("webhook-endpoints", Method.POST);
 
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddJsonBody(new {
data = new {
type = "webhook-endpoints",
attributes = new {
url = "https://api.example.com/v1/keygen"
}
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to mapOf(
"type" to "webhook-endpoints",
"attributes" to mapOf(
"url" to "https://api.example.com/v1/keygen"
)
)
))
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", ofEntries(
entry("type", "webhook-endpoints"),
entry("attributes", ofEntries(
entry("url", "https://api.example.com/v1/keygen")
))
))
));
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value attrs;
attrs["url"] = value::string("https://api.example.com/v1/keygen");
 
value data;
data["type"] = value::string("webhook-endpoints");
data["attributes"] = attrs;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-endpoints");
req.set_method(methods::POST);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>' \
-d '{
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v1/keygen"
}
}
}'

Example response / 201 Created

{
"data": {
"id": "0ed7330f-8d2c-405e-88b6-0a4a327e620c",
"type": "webhook-endpoints",
"links": {
"self": "/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c"
},
"attributes": {
"url": "https://api.example.com/v1/keygen",
"subscriptions": [
"*"
],
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkRetrieve an endpoint

Retrieves the details of an existing endpoint.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the webhook-endpoint to be retrieved.

linkReturns

A 200 OK response will be returned along with a webhook endpoint object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/<id>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c", {
method: "GET",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
Method.GET
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c");
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": {
"id": "0ed7330f-8d2c-405e-88b6-0a4a327e620c",
"type": "webhook-endpoints",
"links": {
"self": "/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c"
},
"attributes": {
"url": "https://api.example.com/v1/keygen",
"subscriptions": [
"*"
],
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkUpdate an endpoint

Updates the specified endpoint resource by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the webhook endpoint to be updated.

linkAttributes

  • linkdata.attributes.url

    stringoptional

    The url that events are dispatched to. Must use the https protocol. Must have a valid SSL certificate. You may include a username and password in the URL, e.g. https://user:[email protected]/webhooks.

  • linkdata.attributes.subscriptions

    array<string>optional

    The event types this webhook endpoint subscribes to. See event types for all options. Use * to listen for all event types.

linkReturns

A 200 OK response will be returned along with the updated webhook endpoint object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/<id>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c", {
method: "PATCH",
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
body: JSON.stringify({
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v2/keygen"
}
}
})
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.patch(
"https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
},
data=json.dumps({
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v2/keygen"
}
}
})
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
method: .patch,
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
],
parameters: [
"data": [
"type": "webhook-endpoints",
"attributes": [
"url": "https://api.example.com/v2/keygen"
]
]
],
encoding: JSONEncoding.default
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
Method.PATCH
);
 
request.AddHeader("Content-Type", "application/vnd.api+json");
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddJsonBody(new {
data = new {
type = "webhook-endpoints",
attributes = new {
url = "https://api.example.com/v2/keygen"
}
}
});
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
import org.json.*
 
val body = JSONObject(mapOf(
"data" to mapOf(
"type" to "webhook-endpoints",
"attributes" to mapOf(
"url" to "https://api.example.com/v2/keygen"
)
)
))
 
val res = Unirest.patch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
import org.json.*;
 
import static java.util.Map.ofEntries;
import static java.util.Map.entry;
 
JSONObject body = new JSONObject(ofEntries(
entry("data", ofEntries(
entry("type", "webhook-endpoints"),
entry("attributes", ofEntries(
entry("url", "https://api.example.com/v2/keygen")
))
))
));
 
HttpResponse<JsonNode> res = Unirest.patch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.body(body)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::json;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
value attrs;
attrs["url"] = value::string("https://api.example.com/v2/keygen");
 
value data;
data["type"] = value::string("webhook-endpoints");
data["attributes"] = attrs;
 
value body;
body["data"] = data;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Content-Type", "application/vnd.api+json");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c");
req.set_method(methods::PATCH);
req.set_body(body.serialize());
 
client.request(req)
.then([](http_response res)
{
auto data = res.extract_json().get();
})
.wait();
curl -X PATCH https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>' \
-d '{
"data": {
"type": "webhook-endpoints",
"attributes": {
"url": "https://api.example.com/v2/keygen"
}
}
}'

Example response / 200 OK

{
"data": {
"id": "0ed7330f-8d2c-405e-88b6-0a4a327e620c",
"type": "webhook-endpoints",
"links": {
"self": "/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c"
},
"attributes": {
"url": "https://api.example.com/v2/keygen",
"subscriptions": [
"*"
],
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkDelete an endpoint

Permanently deletes an endpoint. It cannot be undone.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the endpoint to be deleted.

linkReturns

A 204 No Content response will be returned.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/<id>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c", {
method: "DELETE",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
import requests
 
res = requests.delete(
"https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
)
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
method: .delete,
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let status = response.response?.statusCode
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
Method.DELETE
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c");
req.set_method(methods::DELETE);
 
client.request(req)
.then([](http_response res) {
auto status = res.status_code();
})
.wait();
curl -X DELETE https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 204 No Content

No content

linkList all endpoints

Returns a list of endpoints. The endpoints are returned sorted by creation date, with the most recent endpoints appearing first.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

linkQuery Parameters

  • linklimit

    integerdefault=10

    A limit on the number of endpoints to be returned. Limit must be a number between 1 and 100.

    /v1/accounts/<account>/webhook-endpoints?limit=25
  • linkpage

    object<string, integer>

    Object containing page size and page number. Page size must be a number between 1 and 100.

    /v1/accounts/<account>/webhook-endpoints?page[size]=15&page[number]=2

linkReturns

A 200 OK response will be returned along with a list of webhook endpoint objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints?limit=15", {
method: "GET",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints?limit=15",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints?limit=15",
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("webhook-endpoints", Method.GET);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddParameter("list", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/webhook-endpoints");
uri.append_query("limit", 15);
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/webhook-endpoints?limit=15 -g \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": [
{
"id": "0ed7330f-8d2c-405e-88b6-0a4a327e620c",
"type": "webhook-endpoints",
"links": {
"self": "/v1/accounts/<account>/webhook-endpoints/0ed7330f-8d2c-405e-88b6-0a4a327e620c"
},
"attributes": {
"url": "https://api.example.com/v1/keygen",
"subscriptions": [
"*"
],
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
},
]
}

linkThe event object

Below you will find the various attributes for the event resource, as well as the event resource's relationships. Webhook events are stored for up to 90 days. If longer storage is needed, we recommend listening for and storing the event details on your end.

If security is a concern, or if it's important to confirm the webhook event's authenticity, you can confirm Keygen sent the webhook event by verifying the event's Keygen-Signature header. See signature request verification.

Alternatively, you can request the canonical webhook event data by using the webhook event ID to retrieve the event object.

linkAttributes

  • linkdata.attributes.endpoint

    stringread only

    The endpoint that the event will be sent to.

  • linkdata.attributes.payload

    stringread only

    The event payload in serialized JSON format.

  • linkdata.attributes.event

    stringread only

    The event type.

  • linkdata.attributes.status

    stringread only

    The current status of the event. Possible statuses are: DELIVERING, DELIVERED, FAILING, and FAILED.

  • linkdata.attributes.lastResponseCode

    integerread only

    The last HTTP response code that your webhook endpoint sent in response to the webhook.

  • linkdata.attributes.lastResponseBody

    stringread only

    The last HTTP response body that your webhook endpoint sent in response to the webhook.

  • linkdata.attributes.created

    timestamp (iso8601)read only

    When the event was created.

  • linkdata.attributes.updated

    timestamp (iso8601)read only

    When the event was last updated.

linkRelationships

  • linkdata.relationships.account

    individual

    The account that the event belongs to.

  • linkdata.relationships.environment

    individualent onlyThese relationships are only available for accounts on an Ent tier.

    The environment that the event was for.

Example object

{
"data": {
"id": "e438b26c-79ab-4088-9bbd-17dbb70c429a",
"type": "webhook-events",
"meta": {
"idempotencyToken": "eeb719a7005359c2b1993c90cff455e2749142253c15227d3f7a93048868c5v2"
},
"links": {
"self": "/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a"
},
"attributes": {
"endpoint": "https://api.example.com/keygen",
"payload": "{\"data\":{\"id\":\"438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\",\"type\":\"licenses\",\"links\":{\"self\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\"},\"attributes\":{\"key\":\"438fc3523fb54f0aae0619d6f55ed5f8-aeb27205c6f82479f888d83ff54b73e4-4cde9bc9cbac8f245220428cc1d0ab9c-119beb9ae7373524deb53cc20f7b14v1\",\"expiry\":\"2017-01-27T16:05:26.207Z\",\"encrypted\":true,\"metadata\":{},\"created\":\"2017-01-13T16:05:26.207Z\",\"updated\":\"2017-01-13T16:05:26.207Z\"},\"relationships\":{\"account\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502\"},\"data\":{\"type\":\"accounts\",\"id\":\"436430b4-de65-4b1d-a120-97b231395502\"}},\"product\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/product\"},\"data\":{\"type\":\"products\",\"id\":\"558c385c-ce9f-483a-8339-f8b71792426f\"}},\"policy\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/policy\"},\"data\":{\"type\":\"policies\",\"id\":\"d16e6c26-bfbd-47ae-94d5-d9b899e18cfa\"}},\"user\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/user\"},\"data\":{\"type\":\"users\",\"id\":\"7e401525-a2ae-4998-b4a3-84cc2e8dfa2f\"}},\"machines\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/machines\"}}}}}",
"event": "license.created",
"status": "DELIVERING",
"lastResponseCode": null,
"lastResponseBody": null,
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkRetrieve an event

Retrieves the details of an existing event.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the event to be retrieved.

linkReturns

A 200 OK response will be returned along with a webhook event object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-events/<id>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a", {
method: "GET",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a",
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a",
Method.GET
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a");
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": {
"id": "e438b26c-79ab-4088-9bbd-17dbb70c429a",
"type": "webhook-events",
"meta": {
"idempotencyToken": "eeb719a7005359c2b1993c90cff455e2749142253c15227d3f7a93048868c5v2"
},
"links": {
"self": "/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a"
},
"attributes": {
"endpoint": "https://api.example.com/keygen",
"payload": "{\"data\":{\"id\":\"438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\",\"type\":\"licenses\",\"links\":{\"self\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\"},\"attributes\":{\"key\":\"438fc3523fb54f0aae0619d6f55ed5f8-aeb27205c6f82479f888d83ff54b73e4-4cde9bc9cbac8f245220428cc1d0ab9c-119beb9ae7373524deb53cc20f7b14v1\",\"expiry\":\"2017-01-27T16:05:26.207Z\",\"encrypted\":true,\"metadata\":{},\"created\":\"2017-01-13T16:05:26.207Z\",\"updated\":\"2017-01-13T16:05:26.207Z\"},\"relationships\":{\"account\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502\"},\"data\":{\"type\":\"accounts\",\"id\":\"436430b4-de65-4b1d-a120-97b231395502\"}},\"product\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/product\"},\"data\":{\"type\":\"products\",\"id\":\"558c385c-ce9f-483a-8339-f8b71792426f\"}},\"policy\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/policy\"},\"data\":{\"type\":\"policies\",\"id\":\"d16e6c26-bfbd-47ae-94d5-d9b899e18cfa\"}},\"user\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/user\"},\"data\":{\"type\":\"users\",\"id\":\"7e401525-a2ae-4998-b4a3-84cc2e8dfa2f\"}},\"machines\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/machines\"}}}}}",
"event": "license.created",
"status": "DELIVERING",
"lastResponseCode": null,
"lastResponseBody": null,
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}

linkDelete an event

Permanently deletes an event. It cannot be undone.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the event to be deleted.

linkReturns

A 204 No Content response will be returned.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-events/<id>

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c", {
method: "DELETE",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
import requests
 
res = requests.delete(
"https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
)
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
method: .delete,
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let status = response.response?.statusCode
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c",
Method.DELETE
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.delete("https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c");
req.set_method(methods::DELETE);
 
client.request(req)
.then([](http_response res) {
auto status = res.status_code();
})
.wait();
curl -X DELETE https://api.keygen.sh/v1/accounts/<account>/webhook-events/0ed7330f-8d2c-405e-88b6-0a4a327e620c \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 204 No Content

No content

linkList all events

Returns a list of events. The events are returned sorted by creation date, with the most recent events appearing first.

When listing webhook events, the payload and lastResponseBody attributes will be set to null. To obtain the attribute value, retrieve the webhook event object by its ID.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

linkQuery Parameters

  • linklimit

    integerdefault=10

    A limit on the number of events to be returned. Limit must be a number between 1 and 100.

    /v1/accounts/<account>/webhook-events?limit=25
  • linkpage

    object<string, integer>

    Object containing page size and page number. Page size must be a number between 1 and 100.

    /v1/accounts/<account>/webhook-events?page[size]=15&page[number]=2
  • linkevents

    array

    Array containing events to filter by.

    /v1/accounts/<account>/webhook-events?events[]=license.deleted&events[]=license.revoked

linkReturns

A 200 OK response will be returned along with a list of webhook event objects.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-events

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-events?limit=15", {
method: "GET",
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.get(
"https://api.keygen.sh/v1/accounts/<account>/webhook-events?limit=15",
headers={
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-events?limit=15",
headers: [
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest("webhook-events", Method.GET);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
request.AddParameter("list", 15);
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-events")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.get("https://api.keygen.sh/v1/accounts/<account>/webhook-events")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.queryString("limit", 15)
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
uri_builder uri("/webhook-events");
uri.append_query("limit", 15);
 
req.set_request_uri(uri.to_uri());
req.set_method(methods::GET);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl https://api.keygen.sh/v1/accounts/<account>/webhook-events?limit=15 -g \
-H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 200 OK

{
"data": [
{
"id": "e438b26c-79ab-4088-9bbd-17dbb70c429a",
"type": "webhook-events",
"meta": {
"idempotencyToken": "eeb719a7005359c2b1993c90cff455e2749142253c15227d3f7a93048868c5v2"
},
"links": {
"self": "/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a"
},
"attributes": {
"endpoint": "https://api.example.com/keygen",
"payload": "{\"data\":{\"id\":\"438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\",\"type\":\"licenses\",\"links\":{\"self\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\"},\"attributes\":{\"key\":\"438fc3523fb54f0aae0619d6f55ed5f8-aeb27205c6f82479f888d83ff54b73e4-4cde9bc9cbac8f245220428cc1d0ab9c-119beb9ae7373524deb53cc20f7b14v1\",\"expiry\":\"2017-01-27T16:05:26.207Z\",\"encrypted\":true,\"metadata\":{},\"created\":\"2017-01-13T16:05:26.207Z\",\"updated\":\"2017-01-13T16:05:26.207Z\"},\"relationships\":{\"account\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502\"},\"data\":{\"type\":\"accounts\",\"id\":\"436430b4-de65-4b1d-a120-97b231395502\"}},\"product\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/product\"},\"data\":{\"type\":\"products\",\"id\":\"558c385c-ce9f-483a-8339-f8b71792426f\"}},\"policy\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/policy\"},\"data\":{\"type\":\"policies\",\"id\":\"d16e6c26-bfbd-47ae-94d5-d9b899e18cfa\"}},\"user\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/user\"},\"data\":{\"type\":\"users\",\"id\":\"7e401525-a2ae-4998-b4a3-84cc2e8dfa2f\"}},\"machines\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/machines\"}}}}}",
"event": "license.created",
"status": "DELIVERING",
"lastResponseCode": null,
"lastResponseBody": null,
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
},
]
}

linkEvent actions

Actions for the event resource.

linkManually retry event

Action to manually retry an event. This creates a new event resource with an identical idempotency token.

Be aware that failed events are automatically retried with an exponential backoff. We will perform 15 retries over approximately 3 days. If you're not watching idempotency tokens, manually retrying an event may result in stale or duplicate data being sent to your endpoints. An event is considered failed if the server responds with a non-2xx status code.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges or a product.

linkURL Parameters

  • link<account>

    stringrequired

    The identifier (UUID) or slug of your Keygen account.

  • link<id>

    stringrequired

    The identifier (UUID) of the event to retry.

linkReturns

A 201 Created response will be returned along with the retried webhook event object.

Upon error, an errors object will be returned along with an HTTP status code indicating the type of error. When an error occurs, the data property will not be included.

Definition

https://api.keygen.sh/v1/accounts/<account>/webhook-events/<id>/actions/retry

Example request

const fetch = require("node-fetch")
 
const response = await fetch("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry", {
method: "POST",
headers: {
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
}
})
 
const { data, errors } = await response.json()
import requests
import json
 
res = requests.post(
"https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry",
headers={
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json"
}
).json()
import SwiftyJSON
import Alamofire
 
Alamofire.request("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry",
method: .post,
headers: [
"Accept": "application/vnd.api+json",
"Authorization": "Bearer <token>"
]
).responseJSON { response in
let json = JSON(data: response.data!)
}
using RestSharp;
 
var client = new RestClient("https://api.keygen.sh/v1/accounts/<account>");
var request = new RestRequest(
"webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry",
Method.POST
);
 
request.AddHeader("Accept", "application/vnd.api+json");
request.AddHeader("Authorization", "Bearer <token>");
 
var response = client.Execute(request);
import com.mashape.unirest.http.exceptions.*
import com.mashape.unirest.http.*
 
val res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson()
import com.mashape.unirest.http.exceptions.*;
import com.mashape.unirest.http.*;
 
HttpResponse<JsonNode> res = Unirest.post("https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry")
.header("Authorization", "Bearer <token>")
.header("Accept", "application/vnd.api+json")
.asJson();
#include <iostream>
#include <string>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
 
http_client client("https://api.keygen.sh/v1/accounts/<account>");
http_request req;
 
req.headers().add("Authorization", "Bearer <token>");
req.headers().add("Accept", "application/json");
 
req.set_request_uri("/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry");
req.set_method(methods::POST);
 
client.request(req)
.then([](http_response res) {
auto data = res.extract_json().get();
})
.wait();
curl -X POST https://api.keygen.sh/v1/accounts/<account>/webhook-events/e438b26c-79ab-4088-9bbd-17dbb70c429a/actions/retry \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer <token>'

Example response / 201 Created

{
"data": {
"id": "3119ed21-2f9e-4aa9-8210-5ed0e73f9bef",
"type": "webhook-events",
"meta": {
"idempotencyToken": "eeb719a7005359c2b1993c90cff455e2749142253c15227d3f7a93048868c5v2"
},
"links": {
"self": "/v1/accounts/<account>/webhook-events/3119ed21-2f9e-4aa9-8210-5ed0e73f9bef"
},
"attributes": {
"endpoint": "https://api.example.com/keygen",
"payload": "{\"data\":{\"id\":\"438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\",\"type\":\"licenses\",\"links\":{\"self\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8\"},\"attributes\":{\"key\":\"438fc3523fb54f0aae0619d6f55ed5f8-aeb27205c6f82479f888d83ff54b73e4-4cde9bc9cbac8f245220428cc1d0ab9c-119beb9ae7373524deb53cc20f7b14v1\",\"expiry\":\"2017-01-27T16:05:26.207Z\",\"encrypted\":true,\"metadata\":{},\"created\":\"2017-01-13T16:05:26.207Z\",\"updated\":\"2017-01-13T16:05:26.207Z\"},\"relationships\":{\"account\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502\"},\"data\":{\"type\":\"accounts\",\"id\":\"436430b4-de65-4b1d-a120-97b231395502\"}},\"product\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/product\"},\"data\":{\"type\":\"products\",\"id\":\"558c385c-ce9f-483a-8339-f8b71792426f\"}},\"policy\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/policy\"},\"data\":{\"type\":\"policies\",\"id\":\"d16e6c26-bfbd-47ae-94d5-d9b899e18cfa\"}},\"user\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/user\"},\"data\":{\"type\":\"users\",\"id\":\"7e401525-a2ae-4998-b4a3-84cc2e8dfa2f\"}},\"machines\":{\"links\":{\"related\":\"/v1/accounts/436430b4-de65-4b1d-a120-97b231395502/licenses/438fc352-3fb5-4f0a-ae06-19d6f55ed5f8/machines\"}}}}}",
"event": "license.created",
"status": "DELIVERING",
"lastResponseCode": null,
"lastResponseBody": null,
"created": "2017-01-02T20:26:53.464Z",
"updated": "2017-01-02T20:26:53.464Z"
},
"relationships": {
"account": {
"links": {
"related": "/v1/accounts/<account>"
},
"data": {
"type": "accounts",
"id": "<account>"
}
}
}
}
}