NAV Navbar
shell

Introduction

Welcome to the Cronhooks API! You can use our API to access Cronhooks API endpoints, which can get information on your scheduled webhooks.

Schedules

Schedule a new webhook

  curl https://api.cronhooks.io/schedules /
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <YOUR_API_TOKEN>' \
  -d \
  '{
     "title": "Send email to inactive users",
     "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading subscriptions.",
     "url": "https://example.com/webhooks/inactive-email",
     "timezone": "asia/karachi",
     "method": "POST",
     "headers": {
       "additionalProp1": "string",
       "additionalProp2": "string",
       "additionalProp3": "string"
     },
     "payload": {
       "additionalProp1": "string",
       "additionalProp2": "string",
       "additionalProp3": "string"
     },
     "contentType": "application/json; charset=utf-8",
     "isRecurring": false,
     "cronExpression": "",
     "runAt": "2019-02-01T12:48:26.983Z"
  }'

The above command returns JSON structured like this:

{
   "success": true,
   "error": null,
   "result":
    {
      "id": 1,
      "title": "Send email to inactive users",
      "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading subscriptions.",
      "url": "https://example.com/webhooks/inactive-email",
      "timezone": "asia/karachi",
      "method": "POST",
      "headers": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      },
      "payload": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      },
      "contentType": "application/json; charset=utf-8",
      "status": "scheduled",
      "errorMessage": "",
      "isRecurring": false,
      "cronExpression": "",
      "runAt": "2019-02-01T12:48:26.983Z",
      "creationTime": "2019-02-01T09:35:27.568Z",
      "lastModificationTime": "2019-02-01T09:35:27.568Z"
    }
}

This endpoint creates a new scheduled webhook.

HTTP Request

POST https://api.cronhooks.io/schedules

URL Parameters

Parameter Required Description
title Required title of webhook schedule.
url Required webhook url.
timezone Required IANA Timezone
method Required Http METHOD
headers Optional {} Object
payload Optional {} Object
contentType Required Content Type for recieving webhook
isRecurring Required Trigger webhook repeatedly or not
runAt Required (if isRecurring false) Webhook will be triggered at given DateTime
cronExpression Required (if isRecurring true) Valid cron expression for recurring schedules

List Schedules

curl "https://api.cronhooks.io/schedules?skip=0&limit=10"
  -H "Authorization: Bearer <YOUR_API_KEY>"

The above command returns JSON structured like this:

{
  "success": true,
  "error": null,
  "result":
  {
    "totalCount": 0,
    "items": [
      {
        "id": 1,
        "title": "Send email to inactive users",
        "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading    subscriptions.",
        "url": "https://example.com/webhooks/inactive-email",
        "timezone": "asia/karachi",
        "method": "POST",
        "headers": {
          "additionalProp1": "string",
          "additionalProp2": "string",
          "additionalProp3": "string"
        },
        "payload": {
          "additionalProp1": "string",
          "additionalProp2": "string",
          "additionalProp3": "string"
        },
        "contentType": "application/json; charset=utf-8",
        "status": "scheduled",
        "errorMessage": "",
        "isRecurring": false,
        "cronExpression": "",
        "runAt": "2019-02-01T12:48:26.983Z",
        "creationTime": "2019-02-01T09:35:27.568Z",
        "lastModificationTime": "2019-02-01T09:35:27.568Z"
      }
    ]
  }
}

This endpoint retrieves all scheduled webhooks.

HTTP Request

GET https://api.cronhooks.io/schedules?skip=0&limit=10

Query Parameters

Parameter Required Description
skip Required Number of records to skip.
limit Required Number of records to return in response.

Retrieve a Scheduled Webhook

curl "https://api.cronhooks.io/schedules/1"
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

The above command returns JSON structured like this:

{
  "success": true,
  "error": null,
  "result":
  {
    "id": 1,
    "title": "Send email to inactive users",
    "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading subscriptions.",
    "url": "https://example.com/webhooks/inactive-email",
    "timezone": "asia/karachi",
    "method": "POST",
    "headers": {
      "additionalProp1": "string",
      "additionalProp2": "string",
      "additionalProp3": "string"
    },
    "payload": {
      "additionalProp1": "string",
      "additionalProp2": "string",
      "additionalProp3": "string"
    },
    "contentType": "application/json; charset=utf-8",
    "status": "scheduled",
    "errorMessage": "",
    "isRecurring": false,
    "cronExpression": "",
    "runAt": "2019-02-01T12:48:26.983Z",
    "creationTime": "2019-02-01T09:35:27.568Z",
    "lastModificationTime": "2019-02-01T09:35:27.568Z"
  }
}

This endpoint retrieves a specific schedule.

HTTP Request

GET https://api.cronhooks.io/schedules/{id}

URL Parameters

Parameter Required Description
id Required The ID of the schedule to retrieve

Update Scheduled Webhook

curl "https://api.cronhooks.io/schedules/2"
  -X PUT \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <YOUR_API_TOKEN>' \
  -d \
  '{
     "id": 2,
     "title": "Send email to inactive users",
     "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading subscriptions.",
     "url": "https://example.com/webhooks/inactive-email",
     "timezone": "asia/karachi",
     "method": "POST",
     "headers": {
       "additionalProp1": "string"
     },
     "payload": {
       "additionalProp1": "string",
       "additionalProp2": "string",
       "additionalProp3": "string",
       "additionalProp4": "string"
     },
     "contentType": "application/json; charset=utf-8",
     "isRecurring": true,
     "cronExpression": "*/5 * * * *"
  }'

The above command returns JSON structured like this:

{
  "success": true,
  "error": null,
  "result":
  {
     "id": 2,
     "title": "Send email to inactive users",
     "description": "Send an email to users who are inactive for more than 60 days and offer a discount for upgrading subscriptions.",
     "url": "https://example.com/webhooks/inactive-email",
     "timezone": "asia/karachi",
     "method": "POST",
     "headers": {
       "additionalProp1": "string"
     },
     "payload": {
       "additionalProp1": "string",
       "additionalProp2": "string",
       "additionalProp3": "string",
       "additionalProp4": "string"
     },
     "contentType": "application/json; charset=utf-8",
     "isRecurring": true,
     "cronExpression": "*/5 * * * *",
     "nextRunAt": "2019-02-01T12:48:26.983Z"
  }
}

This endpoint updates a scheduled webhook.

HTTP Request

PUT https://api.cronhooks.io/schedules/{id}

URL Parameters

Parameter Required Description
id Required id of updated schedule.
title Required title of webhook schedule.
url Required webhook url.
timezone Required IANA Timezone
method Required Http METHOD
headers Optional {} Object
payload Optional {} Object
contentType Required Content Type for recieving webhook
isRecurring Required Trigger webhook repeatedly or not
runAt Required (if isRecurring false) Webhook will be triggered at given DateTime
cronExpression Required (if isRecurring true) Valid cron expression for recurring schedules

Delete Scheduled Webhook

curl "https://api.cronhooks.io/schedules/2"
  -X DELETE
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

The above command returns JSON structured like this:

{
  "success" : true,
  "error": null,
}

This endpoint deletes a specific schedule.

HTTP Request

DELETE https://api.cronhooks.io/schedules/{id}

URL Parameters

Parameter Required Description
id Required The ID of the schedule to delete

Trigger Webhook

curl "https://api.cronhooks.io/schedules/2/trigger"
  -X POST
  -H "Authorization: Bearer <YOUR_API_TOKEN>"

The above command returns JSON structured like this:

event payload json { "success" : true, "error": null, }

This endpoint triggers a specific webhook immediately. It does not affect the schedule.

HTTP Request

POST https://api.cronhooks.io/schedules/{id}/trigger

URL Parameters

Parameter Required Description
id Required The ID of the schedule to trigger

Notifications Integrations

Webhook

You will recieve schedule failure payload as follows

{
  "action": "webhook.failed",
  "webhook":
  {
    ...
  }
}

A POST request will be sent to your provided webhook in case of failure if your shceduled webhook does not return 2xx status code.

Slack

In order to integrate Slack with your cronhooks account, you should follow these steps

  1. Go to the "Integrations" page from top right menu of "User Name" and there you will see "Add to Slack" button. Click on it. Cronhooks Slack Integration

  2. "Add to Slack" button will redirect you to the slack auth page where you can choose the channel you want to get Cronhooks alerts to (see the screenshot below). Cronhooks Slack Authorization

  3. After choosing the channel "Authorize" it and you will be redirected back to Cronhooks integrations page. Here you can see all your slack channels in the list. You can add & delete as many channels as you like.

Webhook Signature Verification

To verify the the authenticity that your scheduled webhook was triggered by cronhooks you can check the signature.

ASP.NET

[Route("api/[controller]")]
public class CronhooksFailureWebHook : Controller
{
    // You can find your endpoint's secret in your API Keys settings
    const string secret = "wh_...";

    [HttpPost]
    public void Index()
    {
      var json = new StreamReader(HttpContext.Request.Body).ReadToEnd();
      var computedSignature = ComputeSignature(secret, json);
      var cronhooksSignature = Request.Headers["Cronhooks-Signature"];

      if (SecureCompare(computedSignature, cronhooksSignature))
      {
        // Verified
      }
    }

    private string ComputeSignature(string secret, string payload)
    {
      var secretBytes = Encoding.UTF8.GetBytes(secret);
      var payloadBytes = Encoding.UTF8.GetBytes(payload);

      using (var cryptographer = new HMACSHA256(secretBytes))
      {
        var hash = cryptographer.ComputeHash(payloadBytes);
        return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
      }
    }

    private bool SecureCompare(string a, string b)
    {
      if (a.Length != b.Length)
      {
        return false;
      }

      var result = 0;
      for (var i = 0; i < a.Length; i++)
      {
        result |= a[i] ^ b[i];
      }
      return result == 0;
    }
}

PHP


  // You can find your endpoint's secret in your API Keys settings
  $webhook_secret = 'wh_...';

  $payload = @file_get_contents('php://input');
  $cronhooks_sig_header = $_SERVER['HTTP_CRONHOOKS_SIGNATURE'];

  $signature = computeSignature($payload, $cronhooks_sig_header);

  if(secureCompare($webhook_secret, $signature)){
    // Verified
  }

  private function computeSignature($payload, $secret){
     return hash_hmac("sha256", $payload, $secret);
  }

  private function secureCompare($secret, $computed){
    if(function_exists('hash_equals')){
      return hash_equals($secret, $computed);
    }

    if (strlen($secret) != strlen($computed)) {
      return false;
    }

    $result = 0;
    for ($i = 0; $i < strlen($secret); $i++) {
      $result |= ord($secret[$i]) ^ ord($computed[$i]);
    }
    return ($result == 0);
  }

Errors

The Cronhooks API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- You shouldn't be here.
404 Not Found -- The specified webhook could not be found.
405 Method Not Allowed -- You tried to access a kitten with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
429 Too Many Requests -- You're sending too many requests!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.