Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

What does a webhook look like?

After you subscribe you subscribe to a webhook topic, Scope sends a webhook notification as an HTTP POST to the specified callback url each time an event occurs that pertains to for the specified topic.

By way of example, the default scenario_session/create webhook notification includes the following:

...

  • X-Scope-Topicscenario_session/create

  • X-Scope-Topic-Version1.1

  • X-Scope-API-Version: 3

  • X-Scope-Domain: scopear.com

  • X-Scope-Webhook-Type: node

  • X-Scope-Hmac-Sha256XWmrwMey6OsLMeiZKwP4FppHH3cmAiiJJAweH5Jo4bM=

  • X-Scope-Webhook-Idb54557e4-bdd9-4b37-8a5f-bf7d70bcd043

...

Info

If your organization is equipped with an “on-prem” install of the Scope System, your domain value is likely to be different than the example value above.

Where:

  • X-Scope-Topic (& X-Scope-

...

  • Topic-Version) specify the topic that triggered the webhook

  • X-Scope-

...

  • API-Version specifies the version of the Scope GraphQL API that was used to serialize the webhook event payload

  • X-Scope-Domain

...

  •  specifies the system that sent the webhook

...

...

Info

Currently, all Scope webhook notifications include a value of node for the X-Scope-Webhook-Type header.

...

In the future, we hope to introduce additional types that pertain to events that do not involve GraphQL nodes (e.g. a value of service might indicate that a particular service has become available.

...

Info

If your organization is equipped with an “on-prem” install of the Scope System, your domain value is likely to be different than the example value above.

Body

Code Block
languagejson

Body

Code Block
languagejson
{
  "data": {
    "id": "t5V3S3X8Trt/weWu0A2YHb0cRFJfcRA2rXT3vAGTz1A="
    "url": "https://cms.scopear.com/api/v3/graphql/object/t5V3S3X8Trt/weWu0A2YHb0cRFJfcRA2rXT3vAGTz1A="
    }
  }
}

...

Note

The url provided should only be used as a fallback if you are unable to leverage GraphQL to gather additional information.

REST endpoints are only capable of delivering 1st-class attributes for any given resource (e.g. they can provide a User’s id, name, & email… but cannot provide the scenario_sessions associated with a User).

...

How can I

...

get more information?

By design, the default payloads provide very limited information default, Scope delivers minimalistic payloads in order to encourage integrators to query the Scope GraphQL API for the specific information that they require.See

Using Global GraphQL is a powerful tool that allows integrators to ask for exactly what they need.

See Using Global Node Ids and Exploring the Graph to learn how to use the Scope GraphQL API.

Info

Most relationships (aka “Connections”) are bidirectional in the Scope GraphQL API. This means that given a node in the graph, you can usually to navigate “up” to find parent-like objects (such as organization, viewer, or scenario) as well as as “down” to find child-like objects (such as scenarioSessionEvents, or scenarioSessionCheckboxes).

GraphQL Examples

Given the following webhook:

...

Customizing the payload

In lieu of querying the Scope GraphQL API for additional data after receiving a webhook, you integrators can supply a valid GraphQL query when , in advance, while subscribing to a webhook.

When a query is supplied for with a webhook subscription, it will be executed by the server when preparing each relevant webhook each time that it prepares a notification for delivery, and the result of that execution will replace the default JSON payload.

...

This feature saves integrators from a round trip with the server and reduces the requirements for building integrations (i.e. integrators that supply queries in advance can more easily use platforms like Zapier).

Info

Subscription queries are executed with the context of the user & organization that created the subscription; as if the user had authenticated and executed the query via the API.

...

Created, updated, and deleted topics are available for every GraphQL Object Type that implements the Node Interface (e.g. scenario_session/created, scenario_session/updated, and scenario_session/deleted).

Note

Although updated and deleted topics are available for all Node types, not all Node types can be updated or deleted (e.g. scenario_session). This means that you might never not ever receive a webhook notification for a topic that you have subscribed to.

...

Alternatively, you can retrieve the list of currently available topics at any time by executing the following query against the Scope GraphQL API:

...

To receive webhooks, register a HTTPS endpoint with your app to act as a webhook receiver.

Then, subscribe to a webhook topic and supply said the endpoint registered in the previous step as the callback_url callbackUrl input value. Scope will immediately begin sending your app webhook notifications whenever events occur that pertain to the subscribed specified topic occur.

Webhook subscriptions are scoped to the user and organization that they're registered with.

This means that: a) other users & organizations can't view, modify, or delete the subscriptions you create; and b) subscriptions registered for other organizations will not be triggered by for events that pertain to your organization’s data.

Versioning

The header X-Scope-API-Version specifies the version of the Scope GraphQL API that was used to serialize the webhook event payload.

...

Subscribing to a webhook topic

You can subscribe to a webhook topic by executing the createWebhookSubscription mutation in GraphQL.

If you do not supply a topic version, or ID, to the mutation, the latest available topic version will be used for the topic key that you supply.

If multiple versions are available for a given topic, each may be triggered by different circumstances.

Subscribing to a webhook topic

...

is likely to be triggered by different circumstances or behave differently in some way.

Example

The following example shows how to subscribe for the scenario_session/create webhook topic (via the Scope GraphQL API).

GraphQL Query

Code Block
languagegraphql
mutation {
  createWebhookSubscription(    
    webhookSubscription: {
      topic: { key: 'scenario_session/create' }
      callbackUrl: "https://my-custom-application.com/hooks/scopear"
      sharedSecret: "SOME SUPER SECRET STRING"
    }
  ) {
    errors {
      field
      message
    }
    webhookSubscription {
      id
    }
  }
}

...

Your endpoint needs to be an a valid HTTPS webhook address url with a valid SSL certificate that can correctly process event notifications as described below. You also need to implement verification to make sure webhook requests originate from Scope.

...

Frequency

Scope has implemented both a five second timeout period and a retry period for subscriptionsdelivery. Scope waits five seconds for a response to each webhook request. If there is no response, or an error is returned, then Scope retries the connection 25 retries over the next 21 days.

Note

If there are 25 consecutive failures for a specific notification, or more than 100 errors within a 1 hour period for a specific subscription, then the webhook subscription is automatically disabled.

...

This section contains some procedures to ensure your webhook integration functions as seamlessly as possible.

Filtering webhooks

If you use a single endpoint (aka “callback_url”) to receive multiple subscriptions, you will need to filter requests using the headersAfter having subscribed to one or more webhook topics. it is your responsibility to filter out unwanted notifications. There is no mechanism available to filter events on the server, nor does Scope intend to ever implement such a feature.

The following Ruby example assumes demonstrates how to filters events (assuming that you are only interested in handling updated events for ScenarioSession resources):

Code Block
languageruby
#!/usr/bin/ruby

#
@payload: hash
def handleWebookfilterWebookNotification(headers, body)
  return unless headers['X-Scope-Topic'] == 'scenario_session/updated'
    
  # business logic goes here...
end

...