Skip to content

Instantly share code, notes, and snippets.

@bswinnerton
Last active July 8, 2021 19:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bswinnerton/9ae3b432a8d649fe4890015bd0a86658 to your computer and use it in GitHub Desktop.
Save bswinnerton/9ae3b432a8d649fe4890015bd0a86658 to your computer and use it in GitHub Desktop.

Update June 30, 2021 - API Released!

The webhook deliveries API has been released on GitHub.com as of June 30, 2021. See the blog post. It will be available in the next major release of GitHub Enterprise Server.

For those who have followed along in this gist - the gist below documented various filters that could be used with the endpoints for Listing Webhook Deliveries. For this first GA release of the webhook deliveries API no server-side filtering is available. We hope to be able to release some filtering capability in the future, but for the time being all information used for filtering is available in the API response and can be used for client-side filtering. Please reach out to GitHub support if you have any issues.

Background

Webhooks are a way for our integrators to be notified of predefined GitHub events. Today, webhooks may fail to be delivered for a variety of reasons: severed connections, downtime from GitHub, downtime from the integrator, etc. Right now, we offer the ability to view failed webhook deliveries in the UI and retry them, but we don’t provide a similar set of functionality in our REST or GraphQL API.

Change

We are introducing a REST API that will allow integrators to query the status of webhook deliveries, and trigger redeliveries where needed.

Webhook Deliveries & Redeliveries REST API

Note: To access these API endpoints, you must provide a custom media type in the Accept Header for your requests as part of the API preview:

application/vnd.github.starlord-preview+json

NOTE: To access these API endpoints, please contact andrewholt@github.com or bswinnerton@github.com.

  1. Get all deliveries
  2. Get a single delivery
  3. Create a new delivery attempt

Get all deliveries

GET /repos/:owner/:repo/hooks/:hook_id/deliveries
GET /orgs/:org/hooks/:hook_id/deliveries
GET /app/hook/deliveries

This endpoint will return all deliveries, irrespective of whether or not they are a redelivery.

Parameters

Name Type Description
since string Only deliveries after this datetime will be returned. ISO8601 format: YYYY-MM-DDTHH:MM:SSZ.
until string Only deliveries before this datetime will be returned. ISO8601 format: YYYY-MM-DDTHH:MM:SSZ.
status string Only deliveries of this status will be returned. Can be one of success, failure.
status_codes array of integers Only deliveries which received these status codes will be returned.
events array of strings Only deliveries of this event type and action will be returned. Actions can be specified by using the format: <event>.<action> e.g. issue_comment.created.
redelivery boolean Either true to return only deliveries which were reattempted, or false to return all deliveries. Default: true.
guid string Only deliveries with this guid will be returned. Includes both initial deliveries and reattempted deliveries.
cursor string Indicates the starting delivery id from which the next paged will be fetched. Used for pagination
per_page Integer Defines the maximum size of records fetched. Used for pagination Max value supported: 100. Defaults to: 30

Response

Status: 200 OK
[
  {
    "id": 1,
    "guid": "c7f212c0-6389-11e8-9793-903f54742472",
    "delivered_at": "2018-05-29T17:46:45Z",
    "redelivery": false,
    "duration": 0.500,
    "status": "success",
    "status_code": 204,
    "event": "label",
    "action": "created",
  }
]

Get a single delivery

GET /repos/:owner/:repo/hooks/:hook_id/deliveries/:delivery_id
GET /orgs/:org/hooks/:hook_id/deliveries/:delivery_id
GET /app/hook/deliveries/:delivery_id

Response

The request[payload] and response[payload] attributes return null values by default. To include the contents of the payload, you must pass the include_payload=true query param.

Status: 200 OK
{
  "id": 1,
  "guid": "c7f212c0-6389-11e8-9793-903f54742472",
  "delivered_at": "2018-05-29T17:46:45Z",
  "redelivery": false,
  "duration": 0.500,
  "status": "success",
  "status_code": 204,
  "event": "label",
  "action": "created",
  "request": {
    "truncated": true,
    "headers": "{\"Request URL\": \"https://bswinnerton.ngrok.io/api-playground/brooks\", \"Request method\": \"POST\", \"content-type\": \"application/json\", \"Expect\": \"\", \"User-Agent: GitHub-Hookshot/fba5abc\", \"X-GitHub-Delivery\": \"7713d1d0-ce60-11e8-9d82-5955",
    "payload": "{ \"action\": \"created\", \"label\": { \"id\": 1089229605, \"node_id\": \"MDU6TGFiZWwxMDg5MjI5NjA1\", \"url\": \"https://api.github.com/repos/api-playground/brooks/labels/kittens\", \"name\": \"kittens\", \"color\": \"bfdadc\", \"default\": false }, \"re"
  },
  "response": {
    "truncated": true,
    "headers": "{\"Content-Length\": 0, \"X-Content-Type-Options\": \"nosniff\"}",
    "payload": "OK"
  }
}

Create a new delivery attempt

POST /repos/:owner/:repo/hooks/:hook_id/deliveries/:delivery_id/attempts
POST /orgs/:org/hooks/:hook_id/deliveries/:delivery_id/attempts
POST /app/hook/deliveries/:delivery_id/attempts

Response

Status: 202 Accepted

Timeline

These APIs are available to preview immediately in github.com and GitHub Enterprise Cloud, and were added in GHES 3.0.

Next Steps

Once you’ve had a chance to review or integrate with these APIs, we would love to gather your feedback.

Known Issues

GHES 3.0

  • The redelivery attribute is always false, even when the delivery was a redelivery of an already sent webhook.
  • The redelivery filter does not properly filter webhook deliveries that were redelivered.
  • In order to access the non-truncated request and response payloads, the Accept header must be passed as application/vnd.github.v3.full+json. In future versions, this was moved to a ?include_payload query argument.
@mrpinsky
Copy link

I am trying to use these endpoints to investigate webhook deliveries, but running into a few limitations:

  1. When I GET /app/hook/deliveries/:delivery_id, the response[payload] is always null, regardless of Accept header. I've tried application/vnd.github.starlord-preview+json, application/vnd.github.v3+json, and application/vnd.github.v3.full+json.
  2. When I am using these endpoints, I usually don't know the ID of the delivery that I'm looking for. Rather, I usually want to filter on some data that's in the payload (e.g., repository, pull request ID) so that I can find that payload. It would be great if that data could be added to the index endpoint, or if I could pass query params when making my requests.

@kammerjaeger
Copy link

I'm not from github. For me .../app/hook/deliveries?status=failure works when I use the header (GHE 3.0). This will give you all the ids of failed events. I also tried with delivery_id and it worked too. But I have some other problems...

@bswinnerton
Copy link
Author

👋 @mrpinsky,

  1. When I GET /app/hook/deliveries/:delivery_id, the response[payload] is always null, regardless of Accept header. I've tried application/vnd.github.starlord-preview+json, application/vnd.github.v3+json, and application/vnd.github.v3.full+json.

This is a good catch. I've just updated the documentation to clarify this. We moved away from using HTTP headers to control whether or not to display the contents of the request / response payloads to a new query param: include_payload.

  1. When I am using these endpoints, I usually don't know the ID of the delivery that I'm looking for. Rather, I usually want to filter on some data that's in the payload (e.g., repository, pull request ID) so that I can find that payload. It would be great if that data could be added to the index endpoint, or if I could pass query params when making my requests.

This is great feedback 👍, I've taken this back to the team for us to explore.

@mrpinsky
Copy link

mrpinsky commented Jun 8, 2021

@bswinnerton Thanks! I had tried that query param in the past, but it must have been before you added support. I'll try it again!

@kammerjaeger ?status=failure works for me, too, but unfortunately I get back too many failures. Without the payload information, I can't tell which is the one I'm looking for. (I know, I should cut down on the failures. It's a work in progress)

@kammerjaeger
Copy link

kammerjaeger commented Jun 8, 2021

Good to hear, I only tested the api with a small test repo.
My problem is that "redelivery" is always false, even if it was redelivered (by api or in the web ui). Also the flag "redelivery" does not do anything for me (the output is the same independent of what I set there) so I always get all the failed events even if they were already redelivered and should then be ignored.

@bswinnerton
Copy link
Author

Thank you for calling those out @kammerjaeger. I've added a "known issues" section to the Gist. These should be resolved in GHES 3.1, and are not a problem on dotcom.

@mrpinsky
Copy link

mrpinsky commented Jul 8, 2021

@bswinnerton Following up on my previous feedback,

  1. When I am using these endpoints, I usually don't know the ID of the delivery that I'm looking for. Rather, I usually want to filter on some data that's in the payload (e.g., repository, pull request ID) so that I can find that payload. It would be great if that data could be added to the index endpoint, or if I could pass query params when making my requests.

I started working around this by fetching the guid from the webhook request headers, logging it/attaching it to observability tools, and then using the guid query param from the index endpoint. This was working great, so I'm pretty sad to see that this server-side filter was removed in the release to GA. It would be top of my list for feature requests!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment