# Race photo finder: face search for marathons and races

> Runners upload one selfie and get every course photo they appear in, including the ones where the bib is covered.

Source: https://sightradar.com/use-cases/race-photo-finder

Race photography is a volume problem. A city marathon produces tens of thousands of photos from photographers spread along the course, and the usual way of sorting them, reading the bib number, fails whenever a jacket, an arm or a gel belt covers it. Face search finds the runner instead of the number. SightRadar does not read bibs. If you already tag by bib, face search fills in the photos the bib reader missed.

**Who builds this:** Race photo companies, timing providers and race organisers who sell or give away course photos.

## How it goes together

1. **Create a collection per race edition** (`POST /v1/collections`): One collection per race and year, for example `city-marathon-2026`. This year's runners never match last year's photos, and deleting the edition later is one call. Creating a collection is free.
2. **Batch-index photos as each photographer uploads** (`POST /v1/webhooks  +  POST /v1/batches  (op: "index")`): Register a webhook endpoint once and keep its `webhook_endpoint_id`. Course photos arrive in waves: the start, each kilometre marker, then the finish. Send each upload as a batch of up to 1,000 photo URLs with your own photo key in `external_id` and the `webhook_endpoint_id`. Results come back as one signed webhook per photo, at the batch rate.
3. **Register the runner's selfie once** (`POST /v1/collections/{id}/selfies`): When a runner opens the finder, register their selfie with their bib or entry ID as `userId` and keep the returned `point_id`. If `face_found` is false (sunglasses and a cap often cause this), ask for another photo before they leave the page.
4. **Search by id, and again as more photos land** (`POST /v1/collections/{id}/search-by-id`): Photos keep uploading for hours after the finish. Each time the runner comes back, search with the stored `point_id` at the search-by-id rate instead of uploading the selfie again.
5. **Merge with your bib results**: Show the union of bib-tagged and face-matched photos, and mark face-only matches for the runner to confirm. A finish-line photo with 30 runners in it is still one indexing charge.

Operations: Create collection · Batch index · Register selfie · Search by id.

## What makes race photos hard

- Motion blur, sunglasses, caps and grimaces. Some course photos will yield no usable face, and each one still counts as a processed photo, so drop obvious misses (empty course shots, crowd-only frames) before you upload.
- Crowded starts and finishes. Dense frames full of small faces are where face search beats bib reading, and they cost the same as a single-runner shot because billing is per photo, not per face.
- Repeat visits. Runners check back after the race and again when the full gallery is up. With search-by-id each return visit is one search-by-id charge and no new upload.
- Matching only on request. Run a search only when a runner asks for their own photos. Do not use the index to follow runners along the course or to identify spectators.

## Cost example: A 10,000-runner city marathon

Assumptions (illustrative volumes, not customer data):

- 120,000 course photos, batch-indexed
- 6,000 runners use the finder and register a selfie (real-time rate)
- Each comes back three times: 18,000 searches by id
- About 3 indexed faces per photo (360,000 stored faces) plus 6,000 stored selfies, kept for 2 months

| Line | Quantity | Rate | Cost |
| --- | --- | --- | --- |
| Index course photos | 120,000 | $0.00062 / photo (batch) | $74.40 |
| Register runner selfies | 6,000 | $0.00093 / photo (real-time) | $5.58 |
| Return-visit searches | 18,000 | $0.00062 / search by id | $11.16 |
| Faceprint storage | 360,000 faces + 6,000 selfies × 2 mo | $6.00 / million stored faces / month | $4.39 |
| **Total** | | | **$95.53** |

That is about $0.016 per runner who used the finder. Billing is per photo processed, never per face: a photo with twelve faces is one charge, and a photo with none is still a processed photo. Rates and calculator: https://sightradar.com/pricing

## Consent and GDPR

Not every runner photographed on the course asked to be indexed, and every face in an indexed photo becomes a stored faceprint. Under GDPR a faceprint used to identify someone is special-category biometric data, so as the controller you need a lawful basis for every face you index, not only for the runners who search. Say in the entry terms and on the finder page that course photos are matched by face on request, keep a non-face option (bib search), and delete the race collection when the photo sales window closes. SightRadar acts as your processor under the Data Processing Agreement (https://sightradar.com/dpa). Our responsible-use posture, deletion modes and the controller/processor split are on https://sightradar.com/trust.

## Further reading

- Build face search with a selfie: https://sightradar.com/blog/build-face-search-with-a-selfie
- Guide: selfie registration and search-by-id: https://sightradar.com/docs/guides/selfie-registration
- Guide: batch indexing and webhooks: https://sightradar.com/docs/guides/batch-and-webhooks

## Try it

Create a free account at https://sightradar.com/login (no card) or try the live demo at https://sightradar.com/#demo. API reference: https://sightradar.com/docs. All use cases: https://sightradar.com/use-cases
