Overview

Scholarly provides webhooks to notify your application when events occur in the system. Webhooks are HTTP POST requests sent to a URL you specify, containing information about the event that occurred. Webhooks are a great way to received information about changes in the Scholarly system near-instantaneously. This can be an important tool for keeping other tools or platforms in sync with Scholarly’s data. Scholarly webhooks adhere to the Standard Webhooks specification. Webhooks can be created and configured by navigating to Settings > Webhooks in the Scholarly platform.

Authentication

All webhook requests include a signature in the X-Webhook-Signature header that you can use to verify the request came from Scholarly. The signature is an HMAC-SHA256 hash of the request body using your webhook’s secret key.

Verifying Webhook Signatures

# Example webhook verification in Ruby
def verify_webhook_signature(request)
  signature = request.headers['X-Webhook-Signature']
  body = request.body.read

  expected_signature = "sha256=#{OpenSSL::HMAC.hexdigest('SHA256', webhook_secret, body)}"

  Rack::Utils.secure_compare(signature, expected_signature)
end

Webhook Headers

All webhook requests include the following headers:
HeaderDescription
Content-TypeAlways application/json
User-AgentScholarly-Webhook/1.0
X-Webhook-IdUnique identifier of the webhook configuration
X-Webhook-EventThe type of event (e.g., department.created)
X-Webhook-DeliveryUnique identifier for this delivery attempt
X-Webhook-TimestampUnix timestamp of when the webhook was sent
X-Webhook-SignatureHMAC-SHA256 signature of the request body

Webhook Payload Format

All webhooks use a “thin” payload format that includes minimal information about the event. Your application should use the provided ID to fetch the full resource data via the appropriate API endpoint if needed.
{
  "type": "event.type",
  "timestamp": "2025-01-20T10:30:00Z",
  "data": {
    "id": "resource-uuid"
  }
}

Event Types

Please see the API Reference > Webhooks section in the side bar for a list of all events and their structure.

Retry Behavior

If your webhook endpoint doesn’t respond with a 2xx status code, Scholarly will retry the webhook with exponential backoff:
  • Maximum retries: 5 attempts
  • Retry schedule:
    • 1st retry: 10 seconds
    • 2nd retry: 20 seconds
    • 3rd retry: 40 seconds
    • 4th retry: 80 seconds (1.3 minutes)
    • 5th retry: 160 seconds (2.7 minutes, capped at 1 hour)
After 5 failed attempts, the webhook delivery will be marked as failed and no further retries will be attempted.

Response Requirements

Your webhook endpoint should:
  1. Respond quickly - Process the webhook asynchronously if needed. We recommend responding within 30 seconds.
  2. Return 2xx status - Any 2xx status code (200-299) indicates successful receipt.
  3. Be idempotent - The same webhook may be delivered multiple times due to retries.

Example Webhook Handler

# Ruby/Rails example
class WebhooksController < ApplicationController
  skip_before_action :verify_authenticity_token

  def handle
    # Verify the webhook signature
    unless verify_webhook_signature(request)
      head :unauthorized
      return
    end

    # Parse the webhook payload
    event = JSON.parse(request.body.read)

    # Process the webhook asynchronously
    ProcessWebhookJob.perform_later(event)

    # Respond immediately
    head :ok
  end

  private

  def verify_webhook_signature(request)
    signature = request.headers['X-Webhook-Signature']
    body = request.body.read
    request.body.rewind # Reset for re-reading

    expected = "sha256=#{OpenSSL::HMAC.hexdigest('SHA256', ENV['SCHOLARLY_WEBHOOK_SECRET'], body)}"

    Rack::Utils.secure_compare(signature, expected)
  end
end

Rate Limits

  • Maximum of 100 concurrent webhook deliveries per institution
  • No limit on the number of webhooks per institution
  • No limit on the number of events per webhook

Best Practices

  1. Use HTTPS - Always use HTTPS endpoints for webhooks to ensure data security.
  2. Verify signatures - Always verify webhook signatures to ensure authenticity.
  3. Handle duplicates - Design your system to handle duplicate webhook deliveries idempotently.
  4. Process asynchronously - Queue webhook processing to respond quickly.
  5. Monitor failures - Set up monitoring for failed webhook deliveries.
  6. Use thin payloads - Fetch full resource data via API when needed rather than relying on webhook payload.

Testing Webhooks

During development, you can use tools like:
  • ngrok - Expose your local server to receive webhooks
  • webhook.site - Inspect webhook payloads
  • RequestBin - Create temporary webhook endpoints for testing

Support

For questions about webhooks or to report issues, please contact support@scholarlysoftware.com or open an issue in your customer support channel.