If your flight lands three or more hours late and it flew out of the UK or the EU, the airline usually owes you money. On a long flight that's £520 under UK rules or €600 under EU rules. A lot of people never claim it, and honestly, I get why. You have to find out when the plane really reached the gate, figure out which rules apply, and then get through the airline's claim form.
So for Anakin Forge 2026 I built Claimback, an AI agent that does that work for you. You give it a flight number and a date. It checks what actually happened, reads the law, works out what you're owed and fills in the airline's claim form. Then it stops, because the one thing it's never allowed to do is press Submit.
- Watch a recorded run: https://claimback-kt20.onrender.com
- Demo video: https://youtu.be/Qso_MPN9rk0
- Code: https://github.com/imarpanpatra/claimback
The brief
Anakin Forge asked for an agent that reads the live web, reasons about what it finds, and then acts on it. A delay claim needs all three, which is why I picked it. The facts live on real websites, the reasoning is legal, and the action is a real form on a real airline's site.
I used Anakin for everything that touches the web, and OpenAI (with Gemini as a fallback) for the reasoning. The backend is Node and Express, and the browser part is playwright-core connected to Anakin's cloud browser.
Read: what really happened to the flight
The flight I tested with the whole way through was Air India AI162 from London Heathrow to Delhi on 9 September 2026.
The first surprise was that FlightAware only understands ICAO flight codes. It doesn't know AI162, but it knows AIC162. So the agent starts with an Anakin Wire action that looks up the airline and turns "AI" into "AIC". Then Anakin's URL Scraper fetches the FlightAware page, which has a JSON blob inside it with the last 14 days of scheduled and actual gate times.
For AI162 that said the flight was due at the gate at 00:20 and got there at 03:47. That's 207 minutes late. One source isn't proof, so the agent also checks AirHelp's flight status through Anakin Wire, and it said 207 minutes too.
A few small details mattered more than I expected:
- The law measures delay at the gate, not at takeoff or touchdown. Luckily gate times are exactly what FlightAware records.
- Rounding. A flight that arrives 179.5 minutes late is not three hours late. My first version rounded that up to 180 and would have told you that you were owed money.
- Codeshares. If you type an American Airlines number but British Airways actually flew the plane, the rules follow British Airways. FlightAware tells you who operated the flight, so the agent uses that.
Reason: reading the law without trusting the model
Next the agent works out which laws apply. AI162 left the UK, so UK Regulation 261/2004 applies. India's DGCA rules apply too because Air India is an Indian airline, but they don't pay cash for delays. The route is 6,732 km.
Then the model reads Article 7 live from legislation.gov.uk, decides what's owed, and quotes the sentences it relied on.
A model that's right most of the time isn't good enough when money and law are involved, so it never gets the final word:
- Every quote is checked against the page. If the model "quotes" something that isn't there, the UI flags it. My first version only compared the first 120 characters, so you could glue an invented clause onto a real sentence and it would still pass. Now it checks the whole quote.
- Every amount is checked against a table. Claimback has a built-in table of EU261, UK261, Canadian and Indian rules. The table sets the final figures, and if the model disagrees you see a warning.
For AI162 the table and the model agree on £520. There's also a detail most people miss. On flights over 3,500 km, if you arrive between three and four hours late, the airline is allowed to pay half. So the honest answer is £260 to £520, and that's what Claimback shows.
Act: filling in a real airline form
Anakin Search finds Air India's own EU/UK delay claim form. Claimback opens it in Anakin's cloud browser, which I drive with playwright-core over CDP. The session is recorded, so there's a video of everything it did.
Real airline websites are messy, and this part took the longest:
- Air India's form page never fired
DOMContentLoadedin the cloud browser, so waiting for the page to "load" just timed out. I navigate withwaitUntil: 'commit'and watch for the form fields myself. - Waiting for "any input on the page" didn't work either, because the header has a search box that shows up long before the form does.
- Through the default connection the page sometimes came up blank and only offered "Accept All" cookies. Connecting through a UK exit (
country=GB) gave me the real UK page with a "Reject All" button. That's also where a passenger on this flight would be, so it made sense anyway. - The cookie banner sometimes loaded late and covered the Submit button, so the agent checks for it again before every step.
For each page, the model gets the visible text and a numbered list of the controls on it. It answers with actions like "fill field 3 with 2100000000", and the code does the actual typing.
The rule I got wrong: never press Submit
This is the part I'm most glad I tested properly.
My first "never submit" rule was a regex on button text. If a button said submit, send, confirm or pay, the agent wouldn't click it. It worked on Air India, because their button literally says "Submit".
Then I built a set of trap pages and ran the real form filler against them in Chrome. 8 of the 10 got through. An icon-only button with no text. An image input. A button that said "Claim now". A "Next" button whose script submitted the form. A dropdown that submitted as soon as you changed it. A button that said "Next" until you typed something, and then said "Submit claim".
A regex on labels was never going to cover all of that, so the rule moved into the page itself. Before any of the airline's scripts run, Claimback injects a lock:
function lockSubmissions(watched) {
const attempts = [];
Object.defineProperty(window, '__claimbackBlockedSubmits', { value: attempts });
HTMLFormElement.prototype.submit = function submit() {
attempts.push('form.submit()');
};
HTMLFormElement.prototype.requestSubmit = function requestSubmit() {
attempts.push('form.requestSubmit()');
};
window.addEventListener('submit', (event) => {
event.preventDefault();
event.stopImmediatePropagation();
attempts.push('submit event');
}, true);
// ...plus wrappers around fetch, XMLHttpRequest and sendBeacon
}
await page.addInitScript(lockSubmissions, passengerDetails);
After that, the page has no way to submit a form, whatever the button says or does. Any attempt gets counted, and the agent treats it as the end of the road.
A form isn't the only way to send data, though. A "Continue" button can just call fetch() with your ticket number in the body. So the lock also wraps fetch, XMLHttpRequest and sendBeacon, and blocks any request that carries the passenger's ticket number, booking reference or email.
Every one of those trap pages is now a test that fails if anything gets sent.
The letter
The last step writes a claim letter with the flight, the times, the regulation and the amount. It's there for when a form needs a login or a captcha, or when you'd just rather send an email.
A lesson about picking the model
Near the end I moved the live server from Gemini to OpenAI and tried the smallest model first, gpt-4.1-nano. The amount still came out right, because the table checks it. The rest went wrong in ways a table can't catch. It typed the passenger's full name into the Last Name field, doubled the prefix on the ticket number, and blamed the delay on "bad weather" because it found an unrelated article about fog in Delhi.
On gpt-5-mini the same run was clean. It typed only the digits after the ticket prefix, used just the surname, noticed a disabled dropdown and left it alone, and found no evidence of bad weather.
Guardrails are great for things you can check, like amounts, quotes and sources. For everything else you still need a model that actually follows instructions.
Some numbers
- A full claim takes two to five minutes and about 14 Anakin credits.
- The project has 58 tests that run offline with no keys. Anakin, FlightAware and the models are faked, and the form filler tests use a real local Chrome.
Try it
You can watch the recorded run right now. It's a real run replayed step by step, screenshots from the cloud browser included. Live claims sit behind an access code because each one spends real credits.
The code is on GitHub. If there's an airline or a set of rules you think it should handle next, I'd love to hear about it in the comments.
Claimback isn't legal advice. It just does the boring research and the paperwork, and leaves the final click to you.



Top comments (0)