Webhooks

Header Wave SVG

What are webhooks?

Webhooks are a way for TutorCruncher to push information about events to another app, Zapier for example.

When do webhooks fire?

Webhooks are fired from TutorCruncher every time an action takes place involving a user, or a job. For instance, a webhook would fire when a tutor is created, or a client makes an enquiry.

Click here to view a list of all actions in TutorCruncher and what they mean.

What information does a webhook contain?

The webhook contains information about the user or job it involves.

How can I set up webhooks?

Simply add an integration to your TutorCruncher account (System > Settings > Integrations), and add the webhook URL that you wish your webhooks to be fired to.

Webhooks

Webhook logs

We have webhook logs so that you can monitor any issues with them. Simply go to your integration to view them.

Webhooks

Webhook Signature Verification

We include Signature in the Webhooks header which you can use to verify if the webhook came from TutorCruncher.

Below is a quick example on how to verify your webhook:

import hashlib
import hmac

private_key = 'YOUR_PRIVATE_API_KEY'

# payload example data
b"""{
    "events": [
        {
            "action": "CHANGED_CONTRACTOR_STATUS",
            "verb": "Changed a Tutor\'s status",
            "timestamp": "2020-03-10T12:41:52.819342Z",
            "actor": {"name": "Billy Holiday", "id": 59, "user_id": 58, "url": ""},
            "subject": {
                "model": "Tutor",
                "url": "http://localhost:8000/api/contractors/54/",
                "id": 54,
                "user": {
                    "title": null,
                    "first_name": "Walter",
                    "last_name": "Moore",
                    "email": "walter_moore@testagency.example.com",
                    "mobile": "07806 402 497",
                    "phone": null,
                    "street": "26 Varna Rd",
                    "state": null,
                    "town": "Fulham",
                    "country": "United Kingdom (GB)",
                    "postcode": "SW6 7LD",
                    "latitude": "51.4796469999999999",
                    "longitude": "-0.2082010000000000",
                    "date_created": "2020-02-19T09:29:19.148949Z",
                    "timezone": null,
                },
                "status": "approved",
                "charge_via_branch": false,
                "default_rate": null,
                "qualifications": [],
                "skills": [
                    {"id": 22, "subject": "History", "qual_level": "Key Stage 4"},
                    {"id": 23, "subject": "Portuguese", "qual_level": "Key Stage 4"},
                ],
                "institutions": [],
                "receive_service_notifications": true,
                "review_rating": null,
                "review_duration": "00:00:00",
                "last_updated": "2020-03-10T12:41:52.799386Z",
                "calendar_colour": "MediumOrchid",
                "labels": [],
                "extra_attrs": [
                    {
                        "id": 33,
                        "value": "I have over 20 years of experience teaching physics at City of London University and can help undergraduates prepare for all kinds of exams in physics and mathematics.",
                        "type": "Long Textbox",
                        "machine_name": "contractor-exp",
                        "name": "Teaching Experience",
                    },
                    {
                        "id": 34,
                        "value": "I am a retired academic teacher and want to keep contact with the job I love albeit in a more limited amounts. In free time I love to go angling with my friends.",
                        "type": "Long Textbox",
                        "machine_name": "contractor-bio",
                        "name": "Bio",
                    },
                ],
                "work_done_details": {"amount_owed": 97.5, "amount_paid": 1854.9, "total_paid_hours": "2 09:00:00"},
            },
        }
    ],
    "_request_time": 1583844113,
}"""

def webhook_view(request):
    payload = request.body
    header_signature = request.META['Webhook-Signature']  # Webhook-Signature can be found in the webhooks header
    assert hmac.new(private_key.encode(), payload, hashlib.sha256).hexdigest() == header_signature
    
    ...