Skip to main content
By default, incident.io writes code changes with its own built-in agent. If your team already runs a coding agent, you can delegate the work to it instead. incident.io still owns everything around the change: the investigation, the conversation in the channel, the progress updates, and linking the finished pull request back to the incident. It hands off only the step of writing the code. The point of delegating is that the change is made with all the setup you’ve already built in that tool: your rules and conventions, the MCP servers you’ve connected (including incident.io’s own, so the agent can pull live incident context), and your development environment. The fix comes from the agent your team has already tuned to your codebase, rather than a generic one.

Choosing which agent runs

Which agent writes the change is an explicit choice. In Settings → AI SRE → Code changes you pick one of three options: incident.io’s built-in agent, Cursor, or your own custom platform. The one you select runs for every code change, so connecting more than one is fine. Your selection is always what’s used.

Cursor

Connect Cursor with an API key, and code change requests are handed to a Cursor cloud agent that makes the change and opens the pull request. It runs with your Cursor configuration, including any MCP servers you’ve set up for your repositories, and the resulting pull request is linked back to the incident exactly as the built-in flow would.
If you’d like us to support another hosted agent out of the box, such as Devin, get in touch and we’ll work with you.

Your own platform

If you run an internal coding agent platform, you can connect it directly by implementing the small HTTP interface specified below. We call you to launch and steer agent runs, and you call us back (or let us poll) with status. Your agent opens the pull request with its own credentials in your own infrastructure. We only ever need read access to the repository to attach the finished PR to the incident.
Connect your platform from Settings → AI SRE → Code changes → Custom agent in the dashboard. You’ll need your platform’s endpoint URL (which must start with https://) and a bearer token it issued for us. Everything else, including the webhook signing secret, is handled automatically. You can also give the connection a display name, which Slack uses when narrating the agent’s progress.Each organization can connect one custom agent platform today. If your agents are split across several internal systems, put a thin router in front of them and connect that. The repository field on each launch tells you where to route. Get in touch if you’d like first-class support for multiple connections.

How a delegated task flows

  1. A responder asks for a code change (for example from the incident channel), and we render a self-contained markdown brief: the incident title and reference, the repository, the user’s instructions, our expectations for the PR, and a snapshot of the investigation so far.
  2. We call POST /agents on your platform with the brief and structured identifiers, plus a per-launch webhook URL and signing secret.
  3. Your platform starts a run and responds with a run ID and a link to its own UI, which we surface in Slack.
  4. While the run is in flight, you send signed status callbacks to the webhook, or we poll GET /agents/{id} every 2 minutes. Both work.
  5. Your agent opens a draft PR with its own GitHub credentials and reports finished with the PR URL. We attach the PR to the incident and move the task into review.
  6. If a responder asks for changes, we call POST /agents/{id}/followup with the new instructions, and the same run updates the same PR.

The interface you implement

All endpoints are served from the base URL you configure, authenticated with the bearer token you issue us (Authorization: Bearer <token>). Every request we send carries an X-Incident-Interface-Version header (currently 2026-06-12) so you can tell which revision of this contract you’re being called with. Breaking changes ship under a new version value, announced ahead of time.
EndpointRequired?Purpose
POST /agentsRequiredLaunch a run
GET /agents/{id}RequiredReport run status
POST /agents/{id}/followupStrongly recommendedSend follow-up instructions to a run
POST /agents/{id}/stopOptionalCancel a run (best effort)
GET /pingOptionalUsed by the dashboard’s “Test connection” button
Webhook (you call us)RecommendedPush status instead of waiting for our poll

POST /agents: launch

{
  "task_id": "01JXAMPLE7AXZ2C93K61WBPYEH",
  "prompt": "<self-contained markdown brief>",
  "incident_id": "01JXAMPLE0INCIDENT0ID0000",
  "reference": "INC-123",
  "investigation_id": "01JXAMPLE0INVESTIGATION00",
  "repository": "acme/payments-service",
  "webhook": {
    "url": "https://app.incident.io/webhooks/code-agent/custom/<org_id>",
    "secret": "<hmac secret>"
  }
}
  • task_id is our identifier for the request. Treat it as an idempotency key: if you receive a second launch with a task_id you’ve already started, return the existing run rather than starting another.
  • prompt is the rendered brief. It’s self-contained, so an agent with no other context can act on it.
  • incident_id, reference and investigation_id are also embedded in the prompt, but exposed as structured fields so your harness can fetch live data through our MCP server without parsing markdown. They’re omitted when the task has no incident or investigation.
  • webhook is where to send status callbacks for this run, and the secret to sign them with. You may ignore it and rely on polling, but webhook-driven updates feel noticeably faster in Slack.
Respond within 10 seconds:
{ "id": "run_8f2k1", "url": "https://agents.example.com/runs/run_8f2k1" }
  • id is your opaque run identifier. We include it in every subsequent call.
  • url (optional) links to your platform’s UI for the run and is shown to responders in Slack.
If launching takes longer than that, accept the request, return the run ID immediately, and do the heavy lifting asynchronously.

GET /agents/{id}: status

{
  "id": "run_8f2k1",
  "status": "running",
  "summary": "Reproduced the bug, writing a regression test",
  "pr_url": "",
  "branch": ""
}
  • status is one of running, finished or error.
  • summary is a short progress message. We show the latest one in Slack, so keep it human-readable and current.
  • pr_url is required when reporting finished. A finished status without a PR URL is treated as a failure, not as “almost done”, so report running until the PR exists.
  • branch (optional) is the feature branch the agent pushed to.

POST /agents/{id}/followup: iteration

{ "instructions": "Also handle the retry case in the worker" }
The run picks up the new instructions and finishes by updating the same PR. Implementing this is strongly recommended: it’s what powers “request changes” from the incident channel. Respond running to status calls while the follow-up is in progress, then finished with the same pr_url once the PR is updated.

POST /agents/{id}/stop: cancel

Best effort, no body. We call it when a responder abandons or retries a task. Returning 404 for a run you’ve already cleaned up is fine.

GET /ping: connection test

Return 200 to confirm the endpoint is reachable and the bearer token is valid. The dashboard’s “Test connection” button calls this; platforms that don’t implement it still work, but admins lose the ability to verify the connection before the first real launch.

The webhook you send us

POST the same JSON body as the status response to the per-launch webhook URL, signed with the per-launch secret:
X-Webhook-Signature: sha256=<hex(HMAC-SHA256(secret, raw request body))>
  • Send one whenever the run meaningfully progresses: on completion at minimum, and ideally on summary changes too.
  • Our handling is idempotent, and the webhook and our poller converge on the same logic, so duplicate or out-of-order deliveries are harmless.
  • You don’t need a retry pipeline: if a delivery fails, our 2-minute poll picks the status up. (Retries are welcome all the same.)
  • We respond 200 even for runs we no longer track, so you can fire-and-forget.

Timing expectations

WhatExpectation
Response to any of our callsWithin 10 seconds
Our polling cadenceEvery 2 minutes per active run
Maximum run length2 hours, after which we mark the task as failed
Webhook deliveriesAny time during a run; completion at minimum

What this interface doesn’t do

Instructions flow one way. There is no way for your agent to ask the responder a question mid-run (no elicitation step). If the brief is ambiguous, the agent should make a reasonable choice and explain it in the PR description. Responders iterate after the fact through follow-ups, which is the intended loop.

Giving your agent live incident data

The brief embeds an investigation snapshot capped at 30,000 characters. For full, current context, configure your agent harness with access to our MCP server using an incident.io API key:
  • investigation_sync downloads the complete investigation (findings, hypotheses, check outputs) as an archive via a short-lived signed URL.
  • incident_show and alert_show fetch the live incident and related alerts.
The brief tells the agent to prefer these tools when they’re available and to fall back to the embedded snapshot otherwise, so MCP access is an upgrade, not a requirement.

Security model

There are three credentials in play, each scoped to one direction:
  1. Us → your API: the bearer token you issue and paste into our dashboard. We store it encrypted and send it on every call. Rotate it by reconnecting with a new token.
  2. You → our webhook: the HMAC secret we generate when you connect, delivered to you inside each launch request. You never need to store it long-term. Sign each run’s callbacks with the secret that run was launched with.
  3. Your agent → our MCP: an incident.io API key you create and configure into your agent environment, governed by the same scopes as any other API key.
Your platform must be reachable from the public internet over HTTPS. If it isn’t, talk to us.

Making code changes

How responders ask for a fix from the incident channel.

Remote MCP

Give your agent live incident and investigation data.