← All integrations

Scitor + any webhook

Send ticket data to any service with an HTTP endpoint

Because support tickets are GitHub Issues, any API call you can make from a workflow is an integration. This is the generic pattern underneath the Slack, PagerDuty, Linear, and Teams pages: a workflow file, a repository secret, and a fetch() call. Point it at Zapier, Make, or your own backend.

What this workflow does

It fires once per ticket, when Scitor applies spam:clean, and POSTs a JSON body with the ticket number, title, URL, creation time, and category/sentiment/priority labels to whatever endpoint you configure. Point WEBHOOK_URL at a Zapier Catch Hook and it fans out to Zapier's app catalog; point it at a Make webhook module for the same effect in Make; point it at your own endpoint for anything else.

What it does not do

It sends metadata, not the full ticket body — fetch the issue by number from the GitHub API on your receiving end if you need the complete text. And it does not retry beyond GitHub Actions marking the run failed on a non-2xx response; add your own retry/backoff logic in the script if your endpoint isn't reliably available. It also doesn't de-duplicate — removing and re-applying the trigger label on the same ticket sends a second webhook call, so treat the label as a one-shot trigger or de-duplicate on the receiving end using the ticket number.

The workflow file

Save this as .github/workflows/ticket-webhook.yml in your Scitor-connected repository.

# Ticket webhook (generic)
#
# Sends every new, non-spam Scitor ticket as a JSON payload to any HTTP
# endpoint you control — Zapier, Make, a serverless function, your own
# backend. Use this as the starting point for any service not covered by a
# dedicated integration page.
#
# What this does:
#   - Fires once per ticket, when Scitor applies the `spam:clean` label
#     (meaning AI triage has run and the message is a real inbound request).
#   - POSTs a JSON body with the ticket number, title, URL, created_at, and
#     the category/sentiment/priority labels Scitor applied.
#
# What this does NOT do:
#   - It does not retry on failure beyond GitHub Actions' own step failure —
#     `core.setFailed` marks the run failed if your endpoint returns a
#     non-2xx status, but there's no built-in backoff/retry loop. Add one in
#     the script if your endpoint is not reliably available.
#   - It does not include the full ticket body, only metadata — fetch the
#     issue by number via the GitHub API on your receiving end if you need
#     the full text.
#   - It does not de-duplicate: removing and re-applying the trigger label on
#     the same ticket sends a second webhook call for the same ticket. Treat
#     the label as a one-shot trigger, or de-duplicate on the receiving end
#     using the ticket number.
#
# Required secret:
#   WEBHOOK_URL — the endpoint that should receive the ticket payload (a
#   Zapier "Catch Hook" URL, a Make webhook URL, or your own HTTPS endpoint).
#
# Source: Scitor's own documented example at
# https://support.scitor.io/guides/github-actions#post-to-any-webhook and
# https://support.scitor.io/guides/integrations#zapier /
# https://support.scitor.io/guides/integrations#make-formerly-integromat
# (Scitor's own docs point to this exact pattern for Zapier, Make, and any
# other HTTP-reachable service.)

name: Ticket webhook
on:
  issues:
    types: [labeled]

jobs:
  send-webhook:
    if: >
      github.event.label.name == 'spam:clean' &&
      github.event.issue.user.login == 'scitor-customerops[bot]'
    runs-on: ubuntu-latest
    steps:
      - name: POST ticket payload
        uses: actions/github-script@v7
        with:
          script: |
            const labels = context.payload.issue.labels.map(l => l.name);
            const payload = {
              event: 'ticket.created',
              ticket: {
                number:     context.issue.number,
                title:      context.payload.issue.title,
                url:        context.payload.issue.html_url,
                created_at: context.payload.issue.created_at,
                category:   labels.find(l => l.startsWith('category:'))?.replace('category:', '') ?? null,
                sentiment:  labels.find(l => l.startsWith('sentiment:'))?.replace('sentiment:', '') ?? null,
                priority:   labels.find(l => l.startsWith('priority:'))?.replace('priority:', '') ?? null,
              },
            };

            const res = await fetch(process.env.WEBHOOK_URL, {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify(payload),
            });

            if (!res.ok) core.setFailed(`Webhook returned ${res.status}`);
        env:
          WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}

Required secret

Secret Where to get it
WEBHOOK_URL A Zapier "Catch Hook" trigger URL, a Make webhook module's URL, or any HTTPS endpoint you control. Add it under Settings → Secrets and variables → Actions in your repository.

Questions about this integration

Can I use this to connect Scitor to a tool that doesn't have its own integration page?
Yes — that's exactly what this pattern is for. Any service that accepts an HTTP POST (your own backend, a serverless function, or a Zapier/Make catch hook that then fans out to thousands of other apps) can receive ticket data this way.
What does the payload actually contain?
Ticket number, title, GitHub Issue URL, creation timestamp, and whichever category/sentiment/priority labels Scitor has applied at the time the workflow fires. It does not include the full ticket body — fetch the issue by number from the GitHub API on your receiving end if you need the full text.
Does this work with Zapier or Make specifically?
Yes — point WEBHOOK_URL at a Zapier "Catch Hook" trigger URL or a Make webhook module's URL, and either platform receives the same JSON payload and can route it into their respective app catalogs from there.

If it has an API, it can connect to your support inbox

Takes under 5 minutes. Free tier available. No credit card required.