Use the following curl command to schedule a task with Schedify. Be sure to replace the values with your actual data.
curl -X POST https://api.schedify.dev/v1/schedule \
-H "Content-Type: application/json" \
-d '{
"name": "SendWelcomeEmail",
"payload": {
"user_id": "12345",
"email": "[email protected]"
},
"time": "2025-05-21T15:00:00Z",
"url": "https://yourdomain.com/webhooks/welcome"
}'This request will create a scheduled event that posts the payload to your webhook at the specified time.
You'll receive a response like this:
{
"status":1,
"message":"Webhook event created successfully!",
"data": {
"eventId": "evt_abc123xyz",
"webhookId": "b2953cf3-e9b4-4482-a74a-220288df32f0",
"webhookSecret": "whsec_supersecretkey"
}
}When your scheduled event triggers, Schedify sends a POST request to your webhook URL, along with headers that allow you to verify the request's authenticity.
The payload will be the same as what you originally passed when scheduling the event.
📦 Headers Included:
X-Webhook-Signature: <HMAC signature>
X-Webhook-Timestamp: <Unix timestamp>
X-Webhook-ID: <Webhook ID>Use these headers and the request body to validate the signature. The signature is a base64-encoded HMAC-SHA256 hash, generated using your webhookSecret.
🔐 Signature Generation Logic (Go):
func generateSignature(secret string, webhookID string, payload []byte) (string, int64, error) {
timestamp := time.Now().UTC().Unix()
// webhook_id.timestamp.payload
signingPayload := fmt.Sprintf("%s.%d.%s", webhookID, timestamp, string(payload))
h := hmac.New(sha256.New, []byte(secret))
if _, err := h.Write([]byte(signingPayload)); err != nil {
return "", timestamp, fmt.Errorf("failed to create HMAC: %w", err)
}
signature := base64.RawURLEncoding.EncodeToString(h.Sum(nil))
return signature, timestamp, nil
}To verify the signature:
X-Webhook-ID and X-Webhook-Timestamp from the headers.webhook_id.timestamp.payload.webhookSecret to compute the HMAC-SHA256 signature.X-Webhook-Signature. If they match, the request is authentic.❗️ Reject the request if the signature doesn’t match, or if the timestamp is too old (e.g., older than 5 minutes) to prevent replay attacks.