Help Centre
Integrations and API

How do API webhooks work?

Updated 2 min read

On this page

A webhook lets UtilitySEO tell your server when a scan finishes or fails, instead of your software asking over and over. Set one per project with the API, using PUT /webhook and an https address. We then send a short message to that address within about a minute of each scan ending, signed so you can check it came from us.

Project settings, API keys
API keys, where webhooks are set up too

Set it up

Send this with your API key (see the UtilitySEO API):

PUT /api/v1/webhook
{ "url": "https://dashboard.example.com/hooks/utilityseo", "enabled": true }
  • The address must be https, on the standard port, and on the public internet. Private and internal addresses are refused, and checked again before each delivery.
  • The answer includes a signing secret. It is shown only then: store it safely on your server.
  • GET /webhook shows the webhook and its last delivery, never the secret. DELETE /webhook removes it.
  • Send "rotateSecret": true to get a new secret. A new one is also issued when the address changes.

What we send

For any scan of the project, started in the app or through the API, that finishes or fails:

{ "event": "scan.finished", "scanId": "site_812", "projectId": 27, "type": "site", "score": 78, "finishedAt": "..." }

event is scan.finished or scan.failed (then score is empty). Use scanId to fetch the results.

Check it came from us

Each message carries an X-UtilitySEO-Signature header: t= a time in seconds, and v1= a signature. To check it:

  1. Take the raw body exactly as received, before reading it as JSON.
  2. Work out an HMAC-SHA256 of the time, a full stop, then the body, using your signing secret.
  3. Compare it with v1.
  4. Refuse the message if the time is more than 5 minutes from your clock.

Because the time is inside the signature, a copied message cannot be replayed later. Your developer can ask support@utilityseo.com for ready-made example code.

Answer, retries and switching off

  • Answer with any 2xx status within 10 seconds. Redirects are not followed.
  • Anything else is tried again after 1, 5 and 30 minutes.
  • After 3 deliveries in a row fail every retry, the webhook is switched off. Send PUT /webhook with "enabled": true to turn it back on.
  • A message can occasionally arrive twice. The X-UtilitySEO-Delivery header is the same on every retry, so use it, or scanId, to ignore a repeat.

Questions people ask

Can I have more than one webhook?

One per project. To send to several places, have your server pass the message on.

Can I set a webhook from the app?

Not at the moment. Webhooks are set through the API.

How long do you keep delivery records?

Delivery records are kept for 90 days.

Was this helpful?

Still stuck?

Email support@utilityseo.com and a person will reply, usually within one working day. Free setup help is on every plan, trial included.