---
title: "Queue a batch of horses for paced form collection"
method: POST
path: "/v1/racing/horses/backfill"
tags: ["Racing"]
---

# Queue a batch of horses for paced form collection

`POST /v1/racing/horses/backfill`

## Request

- Base URL: `https://api.puntersedge.online`
- URL: `https://api.puntersedge.online/v1/racing/horses/backfill`
- Auth: API key in header `X-API-Key`

Cost: free to submit. 3 credits per horse when it is delivered.

Hand us a list of horses and we collect their Racing Australia form at a pace RA
tolerates, then hold it for you. This is the supported way to backfill a model:
looping /v1/racing/horses/form yourself will trip RA's bot protection long before a
few thousand horses, and the 503s that follow are shared with every other customer.

Names resolve the same way they do on the form endpoint — against acceptances (about
three days ahead) and every archived result runner — and so do the `pe:` horse_refs
published on results, the live board, the archives and /v1/racing/horses/runs, which is
the spelling to submit if you are working from those. A horse we have never seen comes
straight back in `not_found` rather than being queued, and costs nothing. `ambiguous` is
always empty: a name resolves to one horse (several Racing Australia codes under one name
are the same horse's codes from different days, not several horses).

Horses we already hold a fresh copy of skip the queue and are ready at once — matched on
the HORSE, so a page collected under any of its codes counts and no read of Racing
Australia is spent re-fetching it. A horse already queued for you is not queued twice.

Poll GET /v1/racing/horses/backfill/{job_id} for progress and collect from
/results as rows complete — you do not have to wait for the whole batch.

## Headers

- `X-API-Key` string
- `X-RapidAPI-Proxy-Secret` string

## Request body

- BackfillSubmitIn
  - `horses` string[], required: Horse names, `pe:` horse_refs or `ra:` entry codes, in any mix. Max 500 per call. A name and its horse_ref resolve identically, against acceptances and archived results; an `ra:` code pins one meeting's entry.
  - `label` string, nullable: Your own tag for this batch, echoed back on status.

## Response `200`

Successful Response

- BackfillSubmitOut
  - `job_id` string, required
  - `label` string, nullable
  - `queued` integer, required: Horses accepted and waiting on the worker.
  - `already_stored` integer, required: Horses we already hold a fresh copy of — matched on the HORSE, so a page collected under any of its Racing Australia codes counts. Collectable immediately, still billed at 3 credits each.
  - `duplicates` integer, required: Already queued for you; not queued twice.
  - `not_found` string[]: Names we have never seen on our own feeds.
  - `ambiguous` object[]: Names matching several horses. Re-submit with the runner_ref you meant.
  - `estimated_ready` string, nullable: UTC estimate for the last horse, from the worker's measured pace.

## Other responses

- `401`: Missing or invalid API key. Send `X-API-Key`. See https://puntersedge.online/developers/errors
- `402`: Monthly credit allowance exhausted for this plan. Upgrade at https://puntersedge.online/api/pricing
- `422`: Validation Error
- `429`: Rate limit exceeded for this plan. Honour the `Retry-After` header (seconds) before retrying. See https://puntersedge.online/developers/rate-limits
- `500`: Unexpected server error. Safe to retry with backoff.

---

[API](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api.md) · [All operations](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/llms.txt) · [OpenAPI document](https://skmtc.dev/puntersedge/apis/puntersedge-odds-api/revisions/f35b6aab1946?raw)
