> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scaling.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a source

> Point a Sentry project or a GitHub repository at your organisation, and know when one goes quiet.

A **source** is one team's errors or one team's deploys. It is what tells an
incoming webhook which organisation it belongs to, and it is created from the
Sources screen — nothing here needs database access, and nobody at the other end
needs an account with us.

Connecting one is a **guided sequence**, not a form. Press *Connect a Sentry
source* or *Connect a GitHub repository* on the Sources screen and the dialog
walks you through it one step at a time, handing over each value at the step
that needs it.

<Note>
  **This page is a reference, not a set of instructions to follow alongside the dialog.** Every
  value and every instruction is in the sequence itself. This page exists so you can read what the
  sequence is going to ask before you start it, and so somebody can check our instructions without
  signing in.
</Note>

## The one thing to know before you start

The secret travels in **opposite directions** for the two vendors, and getting
it backwards produces a source that refuses every delivery and looks like a
mistake the other team made.

| Vendor     | Who issues the secret | Which way it travels                                       |
| ---------- | --------------------- | ---------------------------------------------------------- |
| **GitHub** | We do                 | Out, in your message. They paste ours into GitHub          |
| **Sentry** | **Sentry does**       | Back, in their reply. There is no field in Sentry for ours |

A Sentry Internal Integration mints its own **Client Secret** and signs every
delivery with it. There is no field anywhere in Sentry to paste a secret of ours
into. So the two sequences are genuinely different shapes: GitHub is one sitting
and nothing comes back; Sentry is two sittings, days apart, and the last step is
you pasting in what they replied with.

<Info>
  **The GitHub sequence shows the secret once, on one step.** It is stored in plain text — computing
  the delivery signature requires the plaintext — but nothing reads it back, so no screen and no
  route will show it to you again after you close the dialog. The step will not let you move forward
  until you have copied the message, and closing before you have copied asks you once. If it is
  lost, the only route is to rotate it, which stops the webhook the other team already configured
  until they paste the new one in. **The Sentry sequence never shows a secret of ours, because there
  is not one.**
</Info>

## What a finding from this source will say

**Findings say an error is new, and which release it followed. They never say
how often it is firing.** That is the whole shape of what comes back, it is the
same for every source on either Sentry route, and there is nothing at either end
that switches the other half on.

It is worth knowing before you send anything, because it is the one thing a team
lending us their errors expects and does not get.
[How an investigation opens](/guides/how-an-investigation-opens) carries the
reasoning; the short version is that the route we ask for is throttled per issue,
so a rate counted from it is wrong in a direction nobody controls — and where a
rate *can* be counted exactly, it is a number their error tracker already shows
them, better than we could from outside.

You do not have to remember to say it. **The sequence puts it on the step before
you send anything, and the message you copy says it to them in their own words**
— so a team reads it while they are deciding whether to configure a webhook,
rather than after their first quiet fortnight.

## Sentry — four steps, two sittings

The address is minted at step 1, **before any secret exists**, so that the
Webhook URL field Sentry asks for at the moment the integration is created has a
real value to receive. The source exists from that point on and holds no secret
until they reply: it refuses every delivery, and the Sources screen shows it as
*Waiting for their secret* with how long it has been waiting.

<Steps>
  <Step title="Who is this source for?">
    Their name as they would write it. Pressing **Prepare the source** mints the delivery address
    now — nothing is sent anywhere, and the source holds no secret yet.
  </Step>

  <Step title="Send them the address — Sentry issues the secret, not us">
    The delivery address is on the step, in full, and so is the whole message to send them. It tells
    them to create an Internal Integration, put that address in the **Webhook URL** field, turn on
    **Alert Rule Action**, leave every other field exactly as it comes, and send the **Client
    Secret** Sentry then shows them back to your email address — which is on the step too.
  </Step>

  <Step title="Paste the Client Secret Sentry issued them">
    Their reply arrives by email, usually days later. Close the dialog and come back to it from the
    Sources screen — the row's **Paste their Client Secret** button reopens the sequence on this
    step. An empty value is refused: a source holding nothing would compare every delivery against
    nothing.
  </Step>

  <Step title="Connected">
    Signatures verify from here on. The step tells you the date before which the source is
    deliberately quiet, and that the Sources screen is where that date lives from now on.
  </Step>
</Steps>

### What the other team is asked to do

Three things, in this order, and the message you send carries all of them:

1. **Settings → Developer Settings → Custom Integrations → Create New
   Integration → Internal.** The **Webhook URL** field takes the address from
   step 2. **Alert Rule Action** is turned on. Every other field is left exactly
   as it comes — none of them change what reaches us.
2. **Save it.** Sentry then shows a **Client Secret**. That is the only thing we
   need back, and nothing arrives until we have it.
3. **Alerts → Create Alert → Issues.** Any conditions that suit them, with the
   action set to *Send a notification via* that integration. This is what
   actually sends us events.

If Sentry ever regenerates the Client Secret, use **Replace the Client Secret**
on the source and enter the new value. Nothing on their side has to change, and
the source keeps everything it has stored — which matters, because a source that
has stored signals cannot be deleted and remade.

### Which delivery to configure

There are two routes into this product. Ask for the **issue alert rule**.

| Route                                                | Delivery                    |
| ---------------------------------------------------- | --------------------------- |
| **Issue alert rule whose action is the integration** | `event_alert` / `triggered` |
| Error event subscription                             | `error` / `created`         |

**Ask for the alert rule.** It sends the event with its release on it — the
field every finding needs in order to name the deploy it followed — and it is
available on Sentry accounts where the error-event subscription is not. They
create it under **Alerts → Create Alert → Issues**, with the action set to *Send
a notification via* the integration.

The **error event** subscription reaches the same place and we read it just the
same. It is not offered on every Sentry account: where it is not, Sentry refuses
the subscription outright with *"Your organization does not have access to the
error subscription resource."* Asking for it first is what sent the first real
integration into a gate it did not need to pass. Which route a source ended up
on is shown on its own row, read off the deliveries that actually arrived — you
never have to ask them what they are paying for, and we do not record it.

<Warning>
  **Deliveries on the alert-rule route undercount the true event rate, and are meant to be sparse.**
  Sentry throttles an alert action per issue, so one issue firing a hundred times does not send a
  hundred deliveries — and an issue that is not firing at all sends nothing. What arrives says
  *what* is happening and *when it started*; it does not say *how often*, and its absence does not
  say *broken*. Do not build a rate measurement on the count of Sentry deliveries — and note that
  the product does not build one either, on this route or the other one. See [what a finding will
  say](#what-a-finding-from-this-source-will-say).
</Warning>

### The percentage on the source row

Once errors are arriving, the source row says how many of the errors stored this
week carry **no usable release**.

It is read off the release the sending project put on the event, not off
anything of ours. An error with no release still produces a finding — a weaker
one, which cannot say which deploy it followed — so the percentage is a quality
figure and never an outage. Zero is the answer for a source on the alert-rule
route sending events that carry a release.

A high percentage has one ordinary cause and one remedy. The issue route carries
no release at all, so a source configured that way reports 100% and the fix is
to ask for the issue **alert rule** described above. If a source is on the alert
rule and the figure is still high, their events are being sent without a release
set, which is a setting in their own SDK rather than anything in the
integration.

## GitHub — three steps, one sitting

We mint the secret here, it goes out with the address in the same message, and
nothing comes back. There is no third step and no waiting.

<Steps>
  <Step title="Who is this source for?">
    Their name as they would write it. Pressing **Create the source** mints the delivery address and
    the signing secret together. Nothing is sent anywhere yet.
  </Step>

  <Step title="Send them the address and the secret we issued">
    Both values are on the step, in full, and both are in the message. It tells them to add a
    webhook under **repository Settings → Webhooks → Add webhook**, with content type
    `application/json`, subscribed to **Pushes**, **Deployments** and **Deployment statuses**, and
    to leave the rest of the form as it comes. **This is the only time the secret is shown.** The
    step will not move forward until you have copied the message, and closing before you have copied
    asks you once.
  </Step>

  <Step title="Connected">
    The source is ready for its first delivery. Stepping back from here re-shows the secret while
    the dialog is still open — the button says so before you press it — and closing the dialog ends
    the only copy.
  </Step>
</Steps>

Everything else GitHub sends is received, counted and ignored. That is not a
failure — a repository webhook receives every event the repository has.

## Going back through the step that shows the secret

Inside one sitting the sequence is generous; at the edge of it, it stops.

* **Back, while the dialog is open, re-shows the GitHub secret.** The value is
  already on the page, so refusing to draw it again would protect nothing and
  would strand you if your paste went into the wrong window. Every control that
  goes back to it says so in its own label before you press it.
* **Closing the dialog ends the only copy.** Reopening the source lands on a
  screen that says so and names replacement as the only route, with what
  replacement costs attached.
* **Every way out before you have copied — the close button, `Esc`, a click
  outside — asks the same single question.** It is the only confirmation in
  either sequence, and it guards the only irreversible thing in them.

## When a finding can first arrive

Each source is deliberately quiet for its first fortnight, and the exact date is
stated **on the source's own row** as well as in the message you send. The
sequence states it once, on its last step, and tells you the row is where it
lives from then on.

The first days of a source's traffic are what say what normal looks like for it,
and anything raised before that would be raised against nothing. The date is
given out because a suppression window the other team cannot see is
indistinguishable from a broken integration — they would spend two weeks
re-checking a webhook that works. It is the date after which silence starts
being worth a question, and it is the only date on the screen that means that.

The quiet is enforced, not merely promised: nothing raised before that date
reaches you. It is also not the product asleep — investigations still open and
decisions are still written down, and what was held is released to you on the
day the fortnight ends, marked as held. [Your first
fortnight](/guides/your-first-fortnight) is the whole of it.

## Reading the health of a source

The screen separates questions that look identical if you only count signals.

| What you see                         | What it means                                                                                 | What to do                                                                                                                                            |
| ------------------------------------ | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Waiting for their secret**         | Prepared, holding no secret. It refuses every delivery and always will until one is pasted in | Chase the reply, then **Paste their Client Secret** on the row. The row carries how long it has waited, and the date after which the wait is abnormal |
| **Established, waiting**             | Connected, holding a secret; no delivery has arrived yet                                      | Nothing. The row carries the date after which the silence is worth a question                                                                         |
| **Configuring**                      | Delivering, nothing stored, less than 30 minutes old                                          | Nothing — it settles either way                                                                                                                       |
| **Storing**                          | Working                                                                                       | Nothing, but read the ages below it                                                                                                                   |
| **Quiet**                            | Nothing has arrived for longer than the printed figure                                        | Read the row. On a Sentry source this is not a fault report — see below                                                                               |
| **Delivering, storing nothing**      | Deliveries arriving, none of them a kind we read                                              | Ask them to change which delivery they subscribed to                                                                                                  |
| **Was storing, now storing nothing** | It worked, and something changed at the other end                                             | The most urgent one: every outward sign says it is fine                                                                                               |
| **Arriving but refused**             | Deliveries arriving, signatures not matching                                                  | See below — a rotation nobody pasted in, or a Sentry Client Secret that has moved                                                                     |
| **Never connected** / **Stopped**    | A GitHub source that has never delivered, or has gone silent past its figure                  | Check the repository webhook still exists                                                                                                             |

### Waiting for a secret is not the same silence as being quiet

**A source waiting for its Client Secret and a source that is connected and
deliberately quiet are both silent, and only one of them can ever work.** The
screen never lets them read the same. The waiting one is amber rather than red —
a source that has never been up is not down — and three things separate it from
every other row at a glance: the badge names what is missing, the row carries
how many days it has waited, and it is the only silent row with a button on it.

A waiting source cannot sit there unnoticed. It carries, from the day it is
prepared, the **date after which the wait stops being a slow reply**. Past that
date the sentence on the row changes and the source is listed at the top of the
Sources screen among the connections that have stalled.

**Nothing about a stalled connection is sent to the other team automatically.**
Chasing somebody for a reply is a message a person writes, reads and sends. The
row says so, in those words, so that its silence about contacting anyone is not
read as a promise nobody made.

### Quiet is not broken, and on Sentry we cannot tell the difference

**A Sentry source that has sent nothing for days may be perfectly healthy.** On
the alert-rule route the deliveries are throttled per issue and are sent only
when an issue actually fires, so how quiet a healthy source is depends on the
rule that was written and on whether anything is going wrong. A calm week
legitimately produces nothing at all.

So a quiet Sentry row is shown as **Quiet** rather than as a failure, and it
says on the row what it cannot tell you:

> Two things look exactly like this from here and we cannot tell them apart: an
> alert rule that is still in place on a product with nothing going wrong, and
> an integration that no longer exists at Sentry.

That sentence is on **every** quiet Sentry row, not only on the ones that look
suspicious, because there is nothing about a row that makes one reading likelier
than the other. If you need to know which it is, ask them — the product will not
ask for you. **Nothing on this screen sends anything to the team who configured
the source.** Telling somebody their integration looks dead is a message a
person writes and sends.

A GitHub source is read differently, and deliberately: a repository webhook
fires on every push, deployment and deployment status the repository has, so a
repository that has gone silent for longer than its figure has either stopped or
been disconnected.

<Warning>
  **"Arriving but refused" is not a silence, and it is the one most easily mistaken for one.** A
  delivery whose signature does not match stores nothing and counts as no delivery, so a source in
  this state looks quiet from every other angle.

  On a **GitHub** source it almost always means the secret was rotated here and never pasted in on
  their side: send the message again. On a **Sentry** source it means the Client Secret we hold is not
  the one Sentry is signing with — ask them for the current value and use **Replace the Client
  Secret**. Nothing on their side is broken in the meantime.
</Warning>

**The age of the last stored signal is shown per kind, always — including when
the source looks healthy.** A source storing errors every minute while it has
stopped storing deploys is half broken, and a single number averages that away.
A healthy badge over a three-day-old age is what a silently paused integration
looks like, which is the thing worth watching for.

**The route each Sentry source is on is shown on its row**, read off the
delivery types that have actually arrived. That is how you tell an alert rule —
throttled, quiet by design — from an error-event subscription, where a gap in
the deliveries is a gap in the errors themselves. Until something arrives, the
route is not known, and the row says so rather than guessing.

A row stops describing itself as storing after 24 hours of silence for errors
and 72 for deploys. Both figures are printed on the screen and neither has been
measured yet — they are a starting position, not a promise about how quickly
anything is noticed. On a Sentry source the figure decides only when the row
stops saying *Storing*; it never decides that anything is broken.

## What we keep

**We keep every delivery whole, exactly as it was sent** — not a summary of it —
alongside the few fields we read out of it and a running count of which delivery
types arrive.

That is more than it sounds like, and the message you send says so in the same
words. A Sentry error delivery carries stack traces, the request URL with its
headers and its cookies, and any user email address or IP address attached to
the event. A GitHub push carries the name and email address of every commit
author in it. We do not drop fields on the way in, so anything the other team
would rather we did not hold has to be filtered before the delivery leaves them.

We keep the delivery rather than a summary because a figure we publish this
month has to be recomputable against the original when it turns out to be wrong.
The alternative is correcting a number by editing the evidence underneath it.

Everything held for a source is deleted within 7 days of a written request, and
in any case by the date stated in the message.

## Removing a source

**A source that has stored signals cannot be deleted.** The attempt is refused
and the signals survive it. Signals are evidence, and deleting a source as a
tidy-up would take its evidence with it without anybody intending that.

Removing the signals is a separate, deliberate operation: it names one source,
it records who ran it and why, and it leaves a record saying so. Ask us for it
in writing — we act on a request within 7 days.

A source that has never stored anything — including one still waiting for its
Client Secret — is removed from the screen directly. There is nothing to lose.
