# Answer Support Tickets from a Django Codebase

Yes. Your backend sends each ticket to the API, an agent reads your Django code for the cause, and the reply comes back as JSON on your webhook.

[Run this on Rush](https://cloud.getrush.ai/run/answer-support-tickets-from-code/django/), in a Project that has your repository.

## What the agent does

Your support tool receives a ticket and starts one run for it, with the product's repository in `resources` and the customer's question in the prompt. The agent clones the repository into its own cloud sandbox and reads code, not documentation. In a Django product like `healthchecks/healthchecks`, it finds Django 6.1 pinned in `requirements.txt`, the check logic in `hc/api/models.py`, the ping endpoint in `hc/api/views.py`, and the background alerter in `hc/api/management/commands/sendalerts.py`.

For the ticket "why did my check go down when I sent pings every 60 seconds with a 1 minute period?", the agent follows a ping through the code. `Check.ping` in `hc/api/models.py` sets `last_ping` and status on a success or fail, and sets `alert_after` from `going_down_after()`, which is the grace start plus `grace`. For a simple check the grace start is `last_ping + timeout`. `get_status` then returns `grace` once that point passes and `down` once the grace period has passed too. So with a 60 second period, every ping that arrives a little late puts the check into grace, and the agent states how long grace must be for the check to stay up.

It also checks the other paths that turn a check down even when pings arrive on time, because a support answer that misses one is wrong. In `hc/api/views.py` a ping with an exit status above 0 becomes `action = "fail"`, and in `Check.ping` a fail sets status `down`. A `/start` signal sets `last_start`, and `get_status` reports `down` when the grace period after a start passes without the matching success. A `failure_kw` keyword that `match_keywords` finds in the ping body, also in `hc/api/views.py`, marks an on-time ping as a failure, and a check whose `methods` is `POST` turns a GET ping into `ign`, so it never resets the timer. The forms in `hc/front/forms.py` require both `timeout` and `grace` to be at least 60 seconds, which bounds what the customer could have set.

The agent writes the reply the prompt asks for: two short paragraphs in plain language for the customer, the files and line numbers that prove each claim, and a confidence level. It changes no code. If the code allows more than one cause, the answer names the setting or ping that tells them apart, such as whether the check's log shows a start signal or a nonzero exit status.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "A customer asks: why did my check go down when I sent pings every 60 seconds with a 1 minute period? Find the answer in this repository's code, not its docs: follow a ping through hc/api/views.py and Check.ping, get_status and going_down_after in hc/api/models.py, and say which grace, start signal, exit status or keyword filter settings would cause it. Reply with JSON: answer (two short paragraphs a customer can read), files (paths and lines that prove it), and confidence. Do not change code.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is the agent's final answer, the JSON object the prompt asks for. `answer` is two paragraphs a support person can paste into the ticket, written for someone who sees the dashboard rather than the code. `files` lists each claim's source, such as `hc/api/models.py` for `get_status` and `hc/api/views.py` for the exit status rule. `confidence` says how sure the agent is, and lower confidence comes with the question that would settle it.

Your webhook receives it as `data.result` in the `run.completed` payload, up to 16 KiB, which is far more than this reply needs. Your backend parses it, attaches it to the ticket as a draft, and leaves sending to a person. Before sending, the support person opens the cited lines and checks that the answer matches the customer's settings: their timeout, their grace, and whether they use start signals.

The session keeps the whole investigation: every file the agent opened, every search it ran, and the order it read them in. When a reply is challenged, an engineer reads that record instead of repeating the search, and when the same question comes in again, the earlier answer and its citations are there to reuse.

## Run it on every new support ticket

Each new ticket in your help desk calls `POST /o/{org}/sessions` once, with the question in `input` and the repository in `resources`. Send the ticket id as the `Idempotency-Key`, so a help desk that delivers its webhook twice still starts one run, and keep the returned `execution_id` on the ticket.

Set a webhook on the API key and your backend hears back when each run finishes, with the reply in `data.result`. A customer who answers with more detail, such as their check's log, goes to the same session as a follow-up message: the sandbox wakes with the repository and its earlier reading still in place.

## Why run it on Rush?

Support engineers answering behaviour questions from code need a checkout, a search tool and time. A Rush run has the repository cloned in its own sandbox the moment it starts, reads as much of the code as the question needs, and gives your backend a typed reply. Nothing runs on a support person's machine, and the agent does not touch the code.

Many tickets arrive at once, and each gets its own run, up to the key's limit on runs in progress, instead of a queue behind one engineer. Every answer carries its citations and the session's full record, which is what lets a support person send a code-based reply with confidence rather than forward the ticket to engineering.

## Frequently asked questions

### Will the agent change my code?

The prompt tells it not to, and the request asks for an answer rather than a pull request. The session's record shows every command it ran, so you can confirm it only read files.

### Why read the code instead of the docs?

The code is what decides the behaviour the customer saw. In this repository the rules that turn a check down are spread across `Check.ping`, `get_status` and the ping view, including the exit status and start signal paths that a quick read of the docs can miss.

### How do I get the reply as structured data?

Ask for JSON in the prompt, as this request does, and parse `data.result` from the webhook or `result` from `GET /o/{org}/sessions/{id}`. Validate the parsed object in your backend before showing it to anyone.

### Can the agent see the customer's account data?

Only what you send. This request has the repository and the question, nothing from your database. If a ticket needs the customer's check settings, put them in the prompt.
