Can I send webhooks to a server I don't control?

I'm trying to set up some webhooks to listen for Raiser's Edge events and push data to Hubspot via a Workato automation. The idea is that the webhook would reach Workato and from there a job would be executed to push the relevant data to Hubspot. I've been following the instructions and using Postman to perform HTTP requests.

I'm successfully getting or refreshing an OAuth 2.0 token with Postman and using it to authenticate a POST request at https://api.sky.blackbaud.com/webhook/v1/subscriptions with the following body:

{

"webhook_url": "https://webhooks.workato.com/webhooks/rest/MY_ENDPOINT_ID/my-endpoint-name",

"event_type": "com.blackbaud.gift.add.v1"

}

I also added the Bb-Api-Subscription-Key request header with the value I got from my Blackbaud subscriptions.

When I try performing this request, however, I get a 400: Bad Request response with the following details:

{

"type": "urn:blackbaud:webhook-url-handshake-missing-origin-header",

"title": "One or more validation errors occurred.",

"status": 400,

"detail": "Received an unexpected 'WebHook-Allowed-Origin' header value from your webhook URL when performing the CloudEvent's Abuse Protection handshake. The header must equal 'eventgrid.azure.net'. Review our Webhook API documentation to learn more. https://developer.blackbaud.com/skyapi/apis/webhook",

"trace_id": "be3b8d86e8744f7a83f1b2417d4e8423",

"span_id": "3a9089dfc364b0a5"

}

The way I'm reading the detail field here, it seems like the system is expecting the webhook endpoint response to include the WebHook-Allowed-Origin header. I guess this could work if I controlled the server with the endpoint, but in my case that server is controlled by Workato.

Questions

  • Am I understanding the issue correctly: the webhook endpoint needs to respond with a WebHook-Allowed-Origin=eventgrid.azure.net header?
  • How can I achieve this for a server I do not control?
  • Could I launch a separate server to handle the subscription process while still sending the actual webhooks themselves to the Workato endpoint?

Thanks a lot for any insight,

Shawn

Comments

  • Alex Wong
    Alex Wong Community All-Star
    Ninth Anniversary Kudos 5 Facilitator 3 bbcon 2025 Attendee Badge

    @Shawn Inder
    I don't know what Workato does though it will be hard for me to imagine it cannot specify HTTP headers. Not able to do so terribly limits the ability to use RESTful API (not only SKY API).

    You might want to check with Workato support as it may be a configuration that you are not aware of.

  • @Alex Wong
    Thanks, I'll ask them about it. Just to make sure though, can you confirm this is indeed what needs to happen?

  • Alex Wong
    Alex Wong Community All-Star
    Ninth Anniversary Kudos 5 Facilitator 3 bbcon 2025 Attendee Badge

    @Shawn Inder
    I don't work for BB, so I can only go back what is in the tutorial. Meaning since it's in the tutorial, it is require to get webhook to work.

  • @Alex Wong
    Makes sense. However, the documentation doesn't specify whether this is a requirement only during the subscription process or for every webhook sent.

    Unfortunately, Workato have confirmed that they don't support adding custom headers to webhook responses.

    The Blackbaud support team don't cover API usage, so I'm going to have to rely on the community for this. I'm hoping someone else might chime in with something else I can try… I'm guessing anyone trying to send webhooks from the SKY API to a non-custom server will have had this issue since the WebHook-Allowed-Origin header doesn't seem to be part of the HTTP standard (i.e. it's not in the HTTP field name registry), so I would be surprised to find any webhook endpoint that include this header by default…

    I'm thinking of trying a man-in-the-middle server to provide this header for the subscription process, but I'm afraid it won't work since it will need its own URL separate from that of the webhook destination and I don't want to have to maintain a separate server just to pass the traffic along…

    I'll let the community know here if I do try it, in case this can help anyone else.

  • Chris Rodgers
    Chris Rodgers Blackbaud Employee
    Ninth Anniversary Kudos 2 Name Dropper Participant

    @Shawn Inder

    As shown in the tutorial, the CloudEvents's Abuse Protection Handshake occurs as an OPTIONS HTTP request to your webhook URL when provisioning your webhook subscription. Returning the appropriate `WebHook-Allowed-Origin` header (`WebHook-Allowed-Origin: eventgrid.azure.net`) indicates that the endpoint allows webhook messages to be sent from our Origin. This helps limit the potential for developers to provision webhooks to arbitrary URLs that the developer does not control--limiting the potential that our webhook publisher Origin might be used for abuse.

    Once your subscription is provisioned, subsequent requests to your webhook URL (POST HTTP requests) do not need to return this header.

    I'm sorry to hear that Workato does not support your use case. I know other integration service providers, like pipedream, have updated the OPTIONS responses for their webhook URLS to allow all origins (`webhook-allowed-origin: *`). In lieu of allowing users, like yourself, to modify response headers, you could ask Workato if they would consider adding the `webhook-allowed-origin: *` response header to their webhook trigger OPTIONS responses. This would allow Workato to support the CloudEvents specification.

    Otherwise, if you're set on using Workato, you'll need to implement a workaround as you described--essentially creating a webhook elsewhere to proxy the webhook payload to the Workato webhook URL.

  • Thanks @Chris Rodgers

    This is very helpful.

    I will ask Workato about the `WebHook-Allowed-Origin: *` solution, but I think pointing them to the CloudEvents specification might be a good motivation for them to feel like they wouldn't be doing this only for us but for anyone using the CloudEvents specification (didn't know about this, again, very useful).