Integrations
Sentry turns errors into tasks, Vercel, Netlify and Cloudflare show the build in the task, outgoing webhooks send Quiel events to Zapier, n8n and your own services.
A workspace admin sets up both integrations on the Integrations screen. Both are marked Beta for now: they are built and tested on sample data, but have not yet run against a live Sentry or Zapier.
Sentry: an error becomes a task
A new Sentry error turns into a project task. The title is the error message; the description holds the level, location, environment, release, a link to Sentry and the call stack. The agent gets everything it needs to find the spot in its repository.
Connecting
It is connected per project: every Quiel project gets its own address, so frontend errors don't land in the backend project.
- Integrations → the Sentry card → Configure → Connect a project. Pick the project and, if needed, a role. Quiel shows the address. Copy it right away: it can't be shown again.
- In Sentry, open Settings → Developer Settings → Custom Integrations and create an Internal Integration.
- Paste the address into Webhook URL and turn on Alert Rule Action. Under Permissions, grant Issue & Event: Read. Save.
- Copy the integration's Client Secret and paste it into Quiel with "Set signing secret". The address works without it too, but with it every request is checked against Sentry's signature.
- In Sentry, open Alerts and create a rule for the Sentry project you need. Under actions, pick Send a notification via and your integration.
The alert rule is the main path: it is set per Sentry project and with filters, so you decide which errors become tasks. If the integration is subscribed to issue webhooks, every new error group creates a task as well, without filters.
What the task looks like
| Field | Value |
|---|---|
| Type | Bug |
| Priority | fatal → P0, error → P1, warning → P2, anything else → P3 |
| Label | sentry |
| Author | whoever connected the integration; they get notified about the result |
| Status | always backlog, like a GitHub issue |
The task lands in the backlog, like an imported GitHub issue: something that arrives from outside isn't ready for work just by arriving. You decide when to hand it to an agent.
Quiel takes only code locations from Sentry: file, line, function. The source lines that Sentry also sends are not stored: the agent has the source in its repository anyway.
Repeats and regressions
Sentry reports an error every time the rule fires. There is still one task:
- The task is still open. No new task. The repeat is noted in the task's activity feed, at most once an hour.
- The task was accepted and the error came back. A new task is created with a link to the previous one.
- The task was cancelled or deleted. Quiel treats that as a human decision and does not create a new one. If you change your mind, create it by hand.
One address creates at most 30 new tasks an hour. It is a fuse against a release that breaks everything at once: without it the board would turn into a dump within the hour. Repeats of known errors don't count toward the limit. Errors above the limit are rejected, and whoever connected the integration, along with the project managers, gets a notification, at most once an hour. The limit holds when signals arrive at the same moment too: forty new errors arriving at once create exactly 30 tasks.
The address leaked or got lost
Click "New address": the old one stops working immediately. Paste the new one into the Webhook URL of the Sentry integration.
Vercel: build, preview and production
Vercel connects through GitHub: there's nothing to set up in Vercel itself, and it works on any Vercel plan. Vercel for GitHub reports every build to GitHub, and Quiel reads those reports.
What it takes
- The Vercel project is connected to the same GitHub repository as the Quiel project, and that repository is connected to Quiel (see GitHub).
- The Quiel app on GitHub has read access to Commit statuses and Deployments. When the app requests them, GitHub asks the installation owner to accept.
- Commit statuses and
deployment_statusevents aren't turned off in Vercel (Project → Settings → Git). They are on by default.
What you get
- The preview build shows up in the task's Checks, next to GitHub Actions. If it fails, the task can't be accepted when "Require green GitHub checks" is on for the project, and it goes back to the agent just like with red tests.
- A Preview row with an Open button in the task's GitHub card. While a new preview is building, the link to the previous one stays, labeled "Previous preview".
- The agent gets the ready preview address in its assignment and in
get_context, and can check its work on the live page.
In a monorepo, each Vercel project gets its own row: "Preview – web", "Preview – docs".
After the merge: production
Once the task's pull request is merged, Vercel builds the main branch. Quiel recognizes that deployment by the commit the PR landed on the main branch with, whether it was a merge commit, a squash or a rebase:
- the task's GitHub card shows a Production row with the site address;
- when the deployment is ready, the task feed gets a Deployed to production note, and outgoing webhooks receive a
task.deployedevent; - the latest production deployment shows up on the project overview, in the Deploy block.
A redeploy of the same commit is a new note: the code went out again. A failed deployment gives no note; the Production row says "failed" and links to the build.
The same works for anything that creates GitHub deployments in the production environment, such as GitHub Actions with environment: production: GitHub marks that environment as production on its own.
The link points to the deployment's own address (*.vercel.app), not your domain: that is the only address Vercel reports to GitHub. If Deployment Protection is on in the Vercel project (it is for new projects), the link opens the Vercel sign-in first.
Build logs for the agent
Vercel has an official MCP server at https://mcp.vercel.com with OAuth sign-in. Connect it to your agent: npx -y add-mcp https://mcp.vercel.com -g adds it to every installed tool, and the agent can read a failed build's log itself. Quiel doesn't store Vercel keys.
Netlify: build, preview and production
Like Vercel, Netlify connects through GitHub: nothing to set up in Quiel.
- The Netlify site is connected to the same repository as the Quiel project.
- The Quiel app on GitHub has read access to Commit statuses.
- GitHub commit statuses notifications are on in Netlify (Project configuration → Notifications → Deploy notifications). New GitHub-connected sites have them on by default.
What you get: the Netlify build in the task's Checks; a Preview row with an Open button, since Netlify puts the Deploy Preview address right into the successful build status; for a failed build, a Build link to its page in Netlify. The agent gets the ready preview address, as with Vercel.
If Netlify also sets statuses on main branch commits, that build appears in the Deploy block on the project overview.
Deploy block on the project overview
Every project with a connected repository has a Deploy block on its overview. It answers two questions: what is in production right now, and is the main branch green.
- Production: the latest deployment of each production environment, from Vercel, Netlify main branch builds and anything that deploys through GitHub environments. Each row shows the state (ready, building, failed), the commit, the time and an Open button; an unfinished one also links to its build.
- Main branch checks, for its latest commit: GitHub Actions, Vercel and Netlify statuses, Cloudflare checks. Green ones collapse into a single "all N of N passed" line; red and running ones are listed with links.
Every project member sees the block, observers included. A project with several repositories gets a section per repository.
Cloudflare: builds and alerts
Pages and Workers builds are already in task checks. Cloudflare writes check runs to GitHub, and the Quiel app reads them. Connect the Cloudflare project to the same repository as the Quiel project, and the task branch build shows up in its Checks, where "Require green GitHub checks" takes it into account. There's no preview button for Pages yet: Cloudflare posts the address as a pull request comment rather than the way Vercel does.
Cloudflare alerts become tasks, the same way Sentry errors do, on any Cloudflare plan.
- Integrations → Cloudflare → Connect a project. Copy the address.
- On the address, click "Set signing secret" and enter any long random string.
- In Cloudflare: Alerts → Destinations, Create in the Webhooks card. URL is the address from Quiel, Secret is the same string. Save and Test: the test reaches Quiel as "1 received" and doesn't create a task.
- Alerts → Overview → Add: pick what to send, for example Pages Project updates with the Deployment failed event, or Workers alerts. The destination is this webhook.
The task is a bug in the backlog; the description holds the Cloudflare alert text, the policy and the alert type. Repeats of one policy are grouped into one task, as with Sentry. An alert closing (ALERT_STATE_EVENT_END) doesn't touch the task.
Outgoing webhooks
An event in Quiel becomes a POST request to your address. That is enough to connect Quiel to Zapier, n8n, Make or your own service without waiting for a dedicated integration for each.
Events
| Event | When |
|---|---|
task.created | A task was created: by hand, by import, by an agent or from Sentry |
task.status_changed | A task's status changed |
task.commented | A comment on a task, by a human or an agent, with its text |
task.deployed | A production deployment of the task's commit is ready. data.deployment holds the environment, address, who deployed it and the commit. The address can be empty if the deployment reported it after becoming ready |
question.asked | An agent asked a question and is waiting for a human |
approval.requested | An agent is waiting to approve a dangerous command |
project.budget_threshold | A project reached 80% or 100% of its monthly budget |
You can pick events and projects. With no projects picked, events come from all of them, including future ones. Events from before the address was added are not sent.
The body carries facts, not content. The text of a question and the command awaiting approval are not in the event: the address belongs to a third-party service, and there is no reason to give it more than needed. For details, follow the link in the event. The exception is comments: they come with their text (comment.text) so they can be forwarded to a chat. Text over 10,000 characters is cut, and comment.truncated becomes true.
Request format
{
"id": "cmg8x0k2r0001qz",
"type": "task.status_changed",
"occurredAt": "2026-10-04T09:12:44.120Z",
"organization": { "id": "cmg1a2b3c0000xy" },
"data": {
"project": { "id": "cmg…", "key": "WEB", "name": "Website" },
"task": {
"id": "cmg…",
"key": "WEB-42",
"title": "Checkout fails on iOS",
"status": "REVIEW",
"priority": "P1",
"type": "BUG",
"url": "https://dash.quiel.app/projects/…/tasks/…"
},
"from": "IN_PROGRESS",
"to": "REVIEW",
"actor": { "kind": "AGENT" }
}
}Headers: Quiel-Event is the event type, Quiel-Delivery is the delivery ID (same as id in the body), Quiel-Signature is the signature.
Verifying the signature
When you add an address, Quiel shows the signing secret once. The Quiel-Signature header looks like t=1759569164,v1=5d41…, where v1 is the HMAC-SHA256 of the string t.body with that secret, in hex. The timestamp inside the signature protects against replaying an intercepted request.
import crypto from 'node:crypto'
// rawBody is the request body AS A STRING, as received, before JSON.parse.
function verifyQuielSignature(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((part) => part.split('=')))
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false
const expected = crypto
.createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex')
const given = String(parts.v1 ?? '')
return (
given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))
)
}Delivery and retries
- A
2xxresponse within 10 seconds means delivered. Redirects are not followed:3xxcounts as a failure. - Not delivered: retries after 1 minute, 5 and 30 minutes, 2, 6 and 12 hours. Seven attempts in total, about a day.
- A retry comes with the same
id: use it to drop duplicates. - Order is not guaranteed: an event waiting for a retry may arrive after later ones. Rely on
occurredAt. - At most 25 events a time go to one address and the rest go next time, so a slow receiver does not hold up other addresses.
- After 30 failures in a row the address turns itself off: the screen shows it, and whoever added the address plus the workspace admins get a notification. Fix the receiver and turn the address back on: events resume from that moment.
"Send test" sends a ping event through the same path as real ones. The Log shows recent deliveries: response code, number of attempts, reason for failure; a failed delivery can be retried.
Test sends are limited: no more than 5 a minute per address, 30 an hour per workspace and 60 an hour per person. If 20 or more undelivered events have piled up on the address, the test is refused (response 429) until the queue clears: fix the receiver first.
Addresses must be https and point to the public internet: internal network addresses (localhost, 10.x, 192.168.x and the like) are rejected, and Quiel checks again on every send.
Zapier and n8n
They don't need a dedicated integration: both accept a plain POST. The Zapier and n8n cards on the Integrations screen show the steps and the outgoing webhooks themselves.
- Zapier: a Zap with the trigger Webhooks by Zapier → Catch Hook; the address is on the Test tab. Webhooks by Zapier is available on Professional, Team and Enterprise plans.
- n8n: a Webhook node, HTTP Method POST, address is the Production URL. It only accepts requests after the workflow is published (activated). n8n must be reachable from the internet over https.
After adding the address, click "Send test": a ping event reaches Zapier or n8n, and it's handy for building the next steps.