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 retrieve the event directly via the API, or use signature verification.

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.updated When your account is updated The updated account object
account.subscription.paused When your account's subscription is paused The updated account object
account.subscription.resumed When your account's subscription is resumed The updated account object
account.subscription.canceled When your account's subscription is canceled The updated account object
account.subscription.renewed When your account's subscription is renewed The updated account object
account.plan.updated When your account's plan is updated The updated plan object
account.billing.updated When your account's billing is updated The updated billing object
user.created When a user is created The user object
user.updated When a user is updated The updated user object
user.deleted When a user is deleted The deleted user object
user.password-reset When a user requests a password reset The user object and reset token
product.created When a product is created The product object
product.updated When a product is updated The updated product object
product.deleted When a product is deleted The deleted product object
policy.created When a policy is created The policy object
policy.updated When a policy is updated The updated policy object
policy.deleted When a policy is deleted The deleted policy object
policy.pool.popped When a key is popped from a pool The popped key 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
license.created When a license is created The license object
license.updated When a license is updated The updated license object
license.deleted When a license is deleted The deleted 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.expired When a license has expired The expired license object
license.checked-in When a license is checked in The checked in 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.check-in-overdue When a license is overdue for check-in The overdue license object
license.validation.succeeded When a license validation succeeds The validated license object
license.validation.failed When a license validation fails The validated license object
license.usage.incremented When a license's usage is incremented The used license object
license.usage.decremented When a license's usage is decremented The used license object
license.usage.reset When a license's usage is reset The reset 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.reinstated When a license is reinstated The reinstated license object
license.policy.updated When a license's policy relationship has been changed The license object
license.user.updated When a license's user relationship has been changed The 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
machine.created When a machine is created The machine object
machine.updated When a machine is updated The updated machine object
machine.deleted When a machine is deleted The deleted machine object
machine.heartbeat.ping When a machine heartbeat ping is received The pinged machine object
machine.heartbeat.pong When a machine heartbeat monitor determines the machine is still alive (i.e. it received a ping within the heartbeat window) The pinged 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.reset When a machine heartbeat is reset The reset machine object
machine.proofs.generated When a machine offline proof is generated The machine object and the proof
machine.deleted When a machine is deleted The deleted machine object
key.created When a key is created The key object
key.updated When a key is updated The updated key object
key.deleted When a key is deleted The deleted key 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
second-factor.created When a second factor is created The second factor object
second-factor.enabled When a second factor is enabled The enabled second factor object
second-factor.disabled When a second factor is disabled The disabled second factor object
second-factor.deleted When a second factor is deleted The deleted second factor object
entitlement.created When an entitlement is created The entitlement object
entitlement.updated When an entitlement is updated The updated entitlement object
entitlement.deleted When an entitlement is deleted The deleted entitlement object
release.created When a release is created The created release object
release.updated When a release is updated The updated release object
release.replaced When a release is replaced via an upsert The replaced release object
release.deleted When a release is deleted The deleted release object
release.downloaded When a release artifact is downloaded The release artifact object
release.upgraded When a release artifact is upgraded The release artifact object
release.uploaded When a release artifact is uploaded The release artifact object
release.yanked When a release artifact is yanked The release 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

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.subscriptions

    array<string>, default is["*"]

    The event types this webhook endpoint subscribes to.

  • linkdata.attributes.created

    timestamp (ISO8601 format)read only

    When the endpoint was created.

  • linkdata.attributes.updated

    timestamp (ISO8601 format)read only

    When the endpoint was last updated.

linkRelationships

  • linkdata.relationships.account

    individual

    The account 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.

linkURL Parameters

  • link:account

    string, required

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

linkAttributes

  • linkdata.attributes.url

    string, required

    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.

    Options

    • *: Wildcard to subscribe the endpoint to all webhook event types
    • account.updated
    • account.subscription.paused
    • account.subscription.resumed
    • account.subscription.canceled
    • account.subscription.renewed
    • account.plan.updated
    • account.billing.updated
    • user.created
    • user.updated
    • user.deleted
    • user.password-reset
    • product.created
    • product.updated
    • product.deleted
    • policy.created
    • policy.updated
    • policy.deleted
    • policy.pool.popped
    • policy.entitlements.attached
    • policy.entitlements.detached
    • license.created
    • license.updated
    • license.deleted
    • license.expiring-soon
    • license.expired
    • license.checked-in
    • license.check-in-required-soon
    • license.check-in-overdue
    • license.validation.succeeded
    • license.validation.failed
    • license.usage.incremented
    • license.usage.decremented
    • license.usage.reset
    • license.renewed
    • license.revoked
    • license.suspended
    • license.reinstated
    • license.policy.updated
    • license.user.updated
    • license.entitlements.attached
    • license.entitlements.detached
    • machine.created
    • machine.updated
    • machine.deleted
    • machine.heartbeat.ping
    • machine.heartbeat.pong
    • machine.heartbeat.dead
    • machine.heartbeat.reset
    • machine.proofs.generated
    • machine.deleted
    • key.created
    • key.updated
    • key.deleted
    • token.generated
    • token.regenerated
    • token.revoked
    • second-factor.created
    • second-factor.enabled
    • second-factor.disabled
    • second-factor.deleted
    • entitlement.created
    • entitlement.updated
    • entitlement.deleted
    • release.created
    • release.updated
    • release.replaced
    • release.deleted
    • release.downloaded
    • release.upgraded
    • release.uploaded
    • release.yanked
    • release.constraints.attached
    • release.constraints.detached

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.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

    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.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

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

linkAttributes

  • linkdata.attributes.url

    string, optional

    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.

    Options

    • *: Wildcard to subscribe the endpoint to all webhook event types
    • account.updated
    • account.subscription.paused
    • account.subscription.resumed
    • account.subscription.canceled
    • account.subscription.renewed
    • account.plan.updated
    • account.billing.updated
    • user.created
    • user.updated
    • user.deleted
    • user.password-reset
    • product.created
    • product.updated
    • product.deleted
    • policy.created
    • policy.updated
    • policy.deleted
    • policy.pool.popped
    • license.created
    • license.updated
    • license.deleted
    • license.expiring-soon
    • license.expired
    • license.checked-in
    • license.check-in-required-soon
    • license.check-in-overdue
    • license.validation.succeeded
    • license.validation.failed
    • license.usage.incremented
    • license.usage.decremented
    • license.usage.reset
    • license.renewed
    • license.revoked
    • license.suspended
    • license.reinstated
    • license.policy.updated
    • license.user.updated
    • machine.created
    • machine.updated
    • machine.deleted
    • key.created
    • key.updated
    • key.deleted

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.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

    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.

linkURL Parameters

  • link:account

    string, required

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

linkFilters

  • linklimit

    integer, default is10

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

    https://api.keygen.sh/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

    https://api.keygen.sh/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{FILTERS}

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 X-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: queued, working, complete, failed, interrupted or unavailable.

  • 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 format)read only

    When the event was created.

  • linkdata.attributes.updated

    timestamp (ISO8601 format)read only

    When the event was last updated.

linkRelationships

  • linkdata.relationships.account

    individual

    The account that the event belongs to.

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": "queued",
"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 privileges to view the resource: either an admin or a product.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

    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": "queued",
"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.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

    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.

linkAuthentication

  • linkBearer

    required

    An authentication token with admin privileges.

linkURL Parameters

  • link:account

    string, required

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

linkFilters

  • linklimit

    integer, default is10

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

    https://api.keygen.sh/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

    https://api.keygen.sh/v1/accounts/{ACCOUNT}/webhook-events?page[size]=15&page[number]=2
  • linkevents

    array

    Array containing events to filter by.

    https://api.keygen.sh/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{FILTERS}

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": "queued",
"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.

linkURL Parameters

  • link:account

    string, required

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

  • link:id

    string, required

    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": "queued",
"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}"
}
}
}
}
}