Equipe

Equipe Startlist AI

Extension

Docs

Extension docs

Equipe Startlist AI

Startlist AI helps show organizers turn rider PM notes into structured start-list wishes, test those wishes against Equipe's prepared start slots, and export a proposed order back to Equipe.

What The Extension Does

Imports Equipe data

Pulls competitions, starts, riders, horses, horse numbers, and PM notes from the current meeting.

Parses rider wishes

Uses AI to extract wishes such as late starts, near another rider, before or after a break, and spacing or order between a rider's own horses.

Evaluates the order

Moves starts within the existing imported slots and shows which wishes are honored, unhonored, or unenforceable.

Exports changes

Writes the proposed position, start number, and time back to Equipe when those values are available. After a successful export, fulfilled PM todos can also be marked completed in Equipe. Export stops if affected competitions contain ridden or ranked starts.

Before You Start In Equipe

The extension works from Equipe's existing start slots. Prepare the meeting in Equipe first:

  1. 1. Draw every competition. The extension does not create a start list from scratch.
  2. 2. Add planned breaks. Breaks should already exist in the Equipe schedule before import.
  3. 3. Run Equipe's automatic start-time conflict resolver. Use the magic wand in Equipe so the start slots and estimated times are ready. Note the Min between you use there: enter the same value when you evaluate wishes, so Startlist AI keeps the time between each rider's starts that the magic wand gave them.
  4. 4. Verify the order and estimated times. Startlist AI moves starts between the imported slots; it does not recalculate the whole day plan.
  5. 5. Make sure PM notes are entered. Rider PM notes and horse PM notes are imported and parsed as the source wishes.

Workflow

Step 1

Import

Pull the prepared meeting data from Equipe.

Step 2

Parse wishes

Use AI to turn PM notes into structured wishes.

Step 3

Evaluate wishes

Move starts within existing slots, keep each rider's Min between, and check wish status.

Step 4

Export order

Write the proposed order back to Equipe and complete fully resolved PM todos.

Parse Throughput And Rate Limits

Wish parsing fans out to one background job per PM note. The app limits concurrent OpenAI parse requests per organizer/API key, so parsing several meetings at the same time does not multiply traffic past the same organizer's OpenAI rate limit.

Parse concurrency
PARSE_CONCURRENCY=2
Job threads
JOB_THREADS=10
Job processes
JOB_CONCURRENCY=1

Effective parallel parsing is bounded by the lowest of parse concurrency and available job worker capacity. A large meeting often uses more OpenAI tokens per minute than the API key allows. When OpenAI says the per-minute limit is reached, the note is rescheduled with backoff instead of continuing to occupy a worker thread: it waits at least 1 minute plus a random spread of up to 1 minute, so the waiting notes do not all come back at the same moment, and it tries up to 20 times. Parsing simply takes longer; the meeting page shows a per-minute limit message while it waits.

An OpenAI rate/spend limit that does not refill by waiting, such as an API key with no quota or billing left, stops the note at once with a message to check billing. Notes that could not be parsed are marked with the error on the wish inspection page. Parse missing notes then parses only the notes without a current result, so the notes that already worked are not sent to OpenAI again. Parse all again parses every note.

Supported Wish Types

The AI parser turns PM text into structured wishes. Only wishes with real Equipe ids for the rider, horse, competition, and target rider can be acted on by the resolver.

PM notes can be written in Swedish, Dutch, French, German, or English. Politeness wording and abbreviations — such as Dutch “a.u.b.”, “aub”, “ajb”, “graag”, or “gelieve”, French “s.v.p.” or “svp”, and German “bitte” for “please”, and greetings or sign-offs like “alvast bedankt”, “danke”, and “mvg” — are understood as politeness, not as wish content. They do not need to be removed or rewritten before parsing, and they never block a note from being parsed.

Horse names may be misspelled. A close spelling variant of one of the rider's horses, such as “Cappoccino” for “Cappuccino”, is matched to the imported horse. A fence height combined with a wish, such as “110 graag vooraan” or “Amigo in 100cm vanachter”, is read as a competition reference: the parser picks the rider's competition whose name carries that height (“1m10”, “1.10m”, and “110 cm” are the same height) and the horse the rider starts with there.

The parser knows the date of every competition. A weekday or date in a note, such as “vrijdag als eerste” or “Sunday first 10”, limits the wish to that day’s competition. A competition number in the note, such as “H: Dollar Baby / 1: Graag achteraan de proef”, limits the wish to that competition only, even when the horse also starts in other competitions. A horse note without a competition or day applies to every competition where that horse starts.

Wishes Written For Another Rider

Parents, partners, and trainers often write a PM note for someone else, for example “my daughters Lumi and Emma could jump in the beginning of the 110” or “Cappuccino als 1. Pferd” when Cappuccino is ridden by the writer's daughter. When a note names another rider, or a horse that the note's own rider does not start, the parser looks up who actually starts and stores the wish for that rider, in that rider's competition and with that rider's horse. Such a wish shows a For rider label in the rider wishes view and is resolved and exported like any other wish. A wish is never bound to a horse that only another rider starts: if the parser cannot tell which rider is meant, the wish is stored as unparseable so you can correct it with Edit for parsing. The PM note itself stays with the rider who wrote it, so its todo marker is only completed when every wish in that note is honored.

Placement

Requests to start in a part of a competition, in a numeric range, in the last places, or before/after a break. “Early”, “vooraan”, “in het begin”, and similar wording is the front of the competition. “Late”, “at the end”, “achteraan”, and similar wording is treated as the back of the competition, and so is vague wording such as “one of the last ones”. “Last”, “laatste”, “sist”, or “dernier” means exactly the last start, and “last 5” or “laatste 5” means within the last five starts. End or late wording without the word last, such as “op het einde van de proef”, “fin d’épreuve”, “zo laat mogelijk”, or “helemaal achteraan”, is the back of the competition, not the very last start. “Startnummer” without a number, as in “graag startnummer in laatste deel”, is not a start number request. Negative wording such as “niet te vroeg” or “pas trop tôt” is never read as front or back; it is kept as informational for a human. “First 10” is a position range from 1 to 10. Placement wishes must be bound to one horse in one competition.

Zone
front, middle, or back
Range
min and max start positions
Last
last N start positions; 1 is the very last start
Break
before or after, optional offset range

Starting Number

Requests for an exact start number, around a number, or within a start-number range. A bare number with “around”, such as “Rond de 25” or “Around 40”, is a start number, and “als eerste” or “as first” is start number 1. A class number, such as “competition 1”, is not treated as a requested start number. Neither is a time of day, such as “around 9.00”, or a horse label, such as “Paard 2”, which riders use to point out which of their own horses a line is about. A fence height on its own, such as “1m10” or “Handicap 110” in a multi-height competition, is the rider declaring which height they jump and is stored as informational only; a height together with a wish, such as “110 graag vooraan”, refers to the competition of that height. If a PM note says a horse is “crazy”, the parser treats that as a hard request for that horse to start first in every competition where the horse appears; “crazy horse last” is a hard request for the very last start instead. A nervous or scared horse (“nervous horse”, “paard is bang in de paddock”) is informational only and never moves the horse. around means plus or minus one start number. These wishes must be bound to one horse in one competition.

Near Rider

Requests to start near, before, or after another rider. The parser must resolve the other rider with the rider lookup tool and store target_equipe_person_id; a plain name is not enough. A short note that is only a name with a direction, such as “Na Zelie Vanderstichelen”, “Altijd na …”, “Voor …”, or “After …”, counts as a complete after/before wish for the whole rider. The lookup ignores common accent differences, so a note can mention “Léa” even if the imported rider name is stored as “Lea”. Close spelling variants are matched as well, so “Zelie van der sticggelen” still finds “Zelie Vanderstichelen”; if the AI leaves out the target or picks a person whose name does not match the written name, the app looks the written name up itself and only keeps the wish when exactly one rider clearly matches. Otherwise the wish is stored as unparseable so you can correct the name with Edit for parsing. Overall support/travel/coaching requests can be rider-level. Start-list wording inside one concrete horse/competition segment is competition-horse level. Family or group requests such as “the Van Es and De Swert families together” are treated as rider-level near-rider wishes: the names are looked up separately, every clear matching other rider becomes a target, and the current PM rider is not used as their own target.

Own Horse Order And Spacing

Requests about the rider's own horses, either as an explicit horse order (ordered_equipe_horse_ids) or as a time gap. “Nobel first of the 2 horses”, “als tweede paard”, or “en 1er des 2 chevaux” is an order between the rider's own horses, not a start number. With more horses, “als eerste van haar 3 paarden” puts that horse before each of the rider's other horses in the competition. A count before or after one of the rider's own horses, such as “20 paarden voor Valeriane” or “een uur voor het andere paard”, is an order plus about that gap: from the stated distance up to 15 minutes more, so “een uur voor” means 60 to 75 minutes before the other horse, not any time at least an hour earlier. Only “minstens” or “at least” makes it a minimum. Asking for “voldoende tijd tussen” or “enough time between my horses” without a number is not turned into a gap; the Min between you set when evaluating already protects every rider's time between starts. When a note lists positions for several horses without saying which horse gets which, such as “komt met 3 paarden, begin, midden en laatste”, the parser does not put them all on one horse; the unassigned part is kept as informational for a human. If the parser still gives one horse in one competition contradicting parts, such as front and back, those wishes are kept as unparseable for a human, because no start order can honor them. A gap such as “30 starts between” is converted during parsing with the rule of thumb 1 start = about 2 minutes, so it becomes gap_minutes: 60. We store this as time instead of a start count because several arenas and competitions can run in parallel, so “20 starts” is easier and safer to evaluate as about 40 minutes between the rider's own starts. A gap can also be a range with gap_min_minutes and gap_max_minutes. A gap of zero minutes is not a wish and is stored as unparseable.

Info And Unparseable

Non-actionable text is stored as info or unparseable so it can still be reviewed, but the resolver marks it as unenforceable because no start-slot move can satisfy it. Stabling requests are always informational: wording such as “stal/stallen/stalling bij …”, “box naast …”, “écurie avec …”, or “stable next to …” asks for neighbouring stables, not neighbouring start positions, so it never becomes a near-rider wish. If the same note also contains start-list wording, such as “vlak voor of na …”, that part is still parsed as a wish. Use the Info / unparseable filter in the rider wishes view to focus on these notes. If the PM text is clear to the organizer but hard for the parser, use Edit for parsing to save a local parsing override and re-parse that note. This does not change the PM text in Equipe. If Equipe later imports a changed PM for the same note, the local override is kept and marked for review. An operator can also remove an extracted wish that should not be enforced; removed wishes are ignored by the resolver and completed-note export until they are restored.

How The Resolver Works

The resolver does not build a new start list. It keeps Equipe's imported start slots and moves movable starts inside each competition to satisfy as many wishes as possible. Only starts that a wish refers to are placed by the optimizer; every other start keeps its imported relative order and just slides a few slots to make room. A rider without a wish is never thrown to a completely different part of the class.

Movable Starts

Only normal starts move. Pause rows stay fixed and are excluded from moves and gap analysis. The proposed start receives the target slot's position, start number, time, estimated time, and timestamp.

Per-Competition Search

The resolver optimizes one competition at a time. It starts from the imported order, seeds direct placement/starting-number wishes, then tries improving swaps for up to 80 iterations.

Scoring

A hard wish is worth 10 points and a soft wish is worth 1 point, unless a wish has an explicit custom weight. Each moved start costs 0.001 points, so unnecessary moves are avoided. A placement or start-number wish that cannot be honored costs more the further its start ends up from what the rider asked for, so the resolver keeps it as close as it can and does not push it away to make room for someone else. Time between a rider's starts is scored too, see below.

Statuses

Honored means the proposed order satisfies the wish. Unhonored means the wish was actionable but the chosen order does not satisfy it. Unenforceable means required data is missing or the wish cannot be checked by moving start slots.

Resolver Thresholds

Front, middle, back

The resolver divides each competition into thirds using the start's center position: (position - 0.5) / total. Values up to 1/3 are front, values up to 2/3 are middle, and the rest are back. A last wish is honored when the start is within the last N positions of the competition.

Near rider

near is honored when the starts are at most 5 starts apart in the same competition. before and after require the correct side of the target rider; they do not currently require a maximum distance.

Breaks

Breaks are inferred inside each competition from longer gaps between imported start times. The resolver uses est_stamp when present, otherwise the displayed estimated/start time. A gap is treated as a break when it is at least the greater of median gap + 5 minutes and median gap × 2. If no break can be inferred, before/after-break wishes are unenforceable.

Riders with several horses

When you evaluate wishes you enter Min between, the minimum time between a rider's starts on the same day, just like in Equipe's start time check. It starts at 45 minutes and remembers the value of your last evaluation. The resolver measures the time between all of a rider's starts that day, across every competition and arena, and never makes it worse than in your prepared list. A gap that was already shorter than Min between in your list is not held against the result, but it is not made shorter either.

Every minute a rider loses below Min between costs 0.25 points. A soft wish is worth 1 point, so it never costs a rider more than 4 minutes; a hard wish may cost up to 40 minutes. When a rider only asks for the order of their horses, the resolver first lets the horses trade places among the rider's own slots, so the order changes and the time between them stays. Riders without a wish only slide a slot or two when other starts move past them; they may end up to 3 minutes below Min between before that counts. Riders whose own note asks for their horses closer together than Min between are exempt: their wish decides instead.

The result page lists every rider who ends up with less time between starts than in your prepared list, with the gaps before and after, so you can check them in Equipe's start time check.

Own-horse gaps

Own-horse gaps are checked in minutes using the proposed slots' displayed times, measured between the rider's starts in time order. gap_minutes is a minimum gap. gap_min_minutes and gap_max_minutes define an accepted range, which is how “een uur voor” or “20 paarden voor” another own horse is stored. If times are missing, the wish is unenforceable. When the source note says combinations or starts instead of minutes, the parser converts it with 1 start = about 2 minutes before the resolver sees it.

What Export Writes Back

Export writes the proposed start-list values back to Equipe. It writes the new position for every moved start, and also writes start time when it exists in the imported start slots. Start numbers are read from the competition's current startlist in Equipe at the moment you export: the number stays with the slot, so a start that moves into a slot takes over that slot's number and the list stays numbered in running order. This also works when the competition was numbered after the import. If a competition has no start numbers at all, none are written and you can number it in Equipe afterwards as usual.

Start order

Starts are moved into existing Equipe slots. The extension does not create new slots or rewrite the whole schedule. Export stops before writing if affected competitions contain ridden or ranked starts.

PM todo status

Equipe PM notes can use [] for an open todo and [x] for a completed todo. After the start order has been exported and verified, Startlist AI changes [] to [x] only when every parsed item in that rider or horse PM note is fully resolved.

PM notes are completed conservatively

A PM note is left unchanged if any actionable wish in that note is unhonored or unenforceable, if the parser marked part of the note as info or unparseable, if the note has no actionable wishes, or if the live PM text in Equipe has changed since the last import. Horse PM notes are also left unchanged unless every imported copy for that horse is fully resolved.

Privacy And Data Responsibility

The organizer chooses to use their own OpenAI API key. That means the organizer is responsible for deciding whether the meeting's PM notes and related start-list context may be sent to OpenAI for processing.

What is sent to OpenAI

When parsing wishes, the extension sends the PM note text, the current rider name, the rider's imported competitions and horses, and any needed lookup queries/results for riders, horses, or competitions. A horse lookup also returns which rider starts that horse in which competition, and a rider lookup can return that rider's competitions and horses, so that notes written for another rider can be bound correctly.

What the organizer must check

Before parsing, the organizer should make sure they have the right permission/legal basis to process this data with OpenAI and that their OpenAI project has acceptable data retention and data sharing settings.

Retention settings matter

OpenAI data handling depends on the API endpoint, project settings, organization settings, and whether Zero Data Retention is enabled. Check OpenAI's current Data controls in the OpenAI platform and the organization's data sharing settings before using real rider data.

OpenAI API Key

Startlist AI needs an OpenAI API key to parse PM notes. The key is stored encrypted for the organizer and is used only when parsing rider wishes.

How to create the key

  1. Go to platform.openai.com and sign in.
  2. Open the API keys area for the project or organization that should pay for the usage.
  3. Create a new secret key.
  4. Use All permissions / full permissions for the key.
  5. Paste the key into AI access in this extension.
Current parser model
gpt-5.4
Permission level
All / full permissions

Keep the key private. Do not paste personal ChatGPT credentials here; this must be an OpenAI API key.

Important Limits

  • The AI parser can misunderstand ambiguous notes. Use the rider wishes view to inspect original text vs. extracted data. Individual PM notes can be parsed again from that view; the note card updates in place when the new result is ready.
  • The resolver only moves starts inside imported slots. It does not invent new slots or redesign the schedule.
  • Export is blocked when affected competitions contain ridden or ranked starts, so live competition data is not overwritten.