RaceTagger API

AI-powered sports & motorsport photo recognition. Detect bib numbers, license plates, aircraft markings. Match detections to participant data.

v1 — StableBase URL: https://racetagger.cloud/api/v1

Quick Start

curl -X POST https://racetagger.cloud/api/v1/analyze \
  -H "Authorization: Bearer rt_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/race-photo.jpg",
    "category": "motorsport"
  }'

Request an API key to get started. Sandbox tier: 100 free credits/month.

Authentication

All endpoints require an API key passed via the Authorization header:

Authorization: Bearer rt_live_your_key

Key formats: rt_live_xxx (production) or rt_test_xxx (sandbox)

Keys are tied to a tier that determines credits and rate limits.

POST

/api/v1/analyze

1 credit

Analyze a single image. Detects vehicles/participants, race numbers, sponsors, and visual features.

Request

{
  "image_url": "https://example.com/photo.jpg",  // OR image_base64
  "category": "motorsport",                       // optional
  "options": {
    "enable_visual_matching": true,                // optional
    "min_confidence": 0.5                          // optional
  }
}

Response

{
  "success": true,
  "analysis_id": "exec_abc123",
  "processing_time_ms": 2340,
  "detection": {
    "method": "hybrid",
    "total_vehicles": 2,
    "vehicles": [
      {
        "vehicle_index": 0,
        "position": "center",
        "race_number": "46",
        "confidence": 0.95,
        "visual_features": {
          "vehicle_colors": ["#FFD700", "#0000FF"],
          "sponsors": ["Monster Energy", "Yamaha"],
          "brand": "Yamaha"
        },
        "bounding_box": { "x": 120, "y": 80, "width": 340, "height": 260 }
      }
    ]
  },
  "metadata": {
    "race_numbers": ["46"],
    "sponsors": ["Monster Energy", "Yamaha"],
    "category": "motogp"
  },
  "credits": { "consumed": 1, "remaining": 99 }
}

Python Example

import requests

resp = requests.post(
    "https://racetagger.cloud/api/v1/analyze",
    headers={"Authorization": "Bearer rt_live_your_key"},
    json={"image_url": "https://example.com/photo.jpg", "category": "motorsport"}
)
data = resp.json()
for v in data["detection"]["vehicles"]:
    print(f"#{v['race_number']} — confidence: {v['confidence']}")
POST

/api/v1/match

FREE — 0 credits

Match previously detected race numbers against a participant list. Handles OCR errors, generates filenames, keywords, and descriptions. This endpoint is free.

Request

{
  "analysis_id": "exec_abc123",
  "participants": [
    { "number": "46", "name": "Valentino Rossi", "team": "Yamaha Factory" },
    { "number": "93", "name": "Marc Marquez", "team": "Repsol Honda" }
  ]
}

Response

{
  "success": true,
  "analysis_id": "exec_abc123",
  "matches": [
    {
      "detection_number": "46",
      "participant": {
        "number": "46", "name": "Valentino Rossi",
        "team": "Yamaha Factory", "category": null
      },
      "confidence": 1.0,
      "match_type": "exact"
    }
  ],
  "unmatched_detections": [],
  "suggested_filename": "motogp_46_Valentino-Rossi",
  "keywords": ["motogp", "#46", "Valentino Rossi", "Yamaha Factory"],
  "description": "motogp photo featuring Valentino Rossi (#46)",
  "credits": { "consumed": 0, "remaining": 99 }
}

Match Types

  • exact — Number matches exactly
  • corrected — OCR error was corrected (e.g. "48" detected, "46" matched)
  • visual — Matched by colors/livery when number unreadable
  • ambiguous — Multiple matches, best guess + alternatives
POST

/api/v1/analyze-and-match

1 credit

Combined endpoint: analyze image + match participants in one call. Saves a round-trip.

{
  "image_url": "https://example.com/photo.jpg",
  "category": "running",
  "participants": [
    { "number": "1234", "name": "John Doe", "team": "NYC Runners" },
    { "number": "5678", "name": "Jane Smith" }
  ]
}
POST

/api/v1/analyze/batch

1 credit/image

Analyze up to 50 images in parallel. Credits consumed only for successful analyses.

{
  "images": [
    { "image_url": "https://example.com/photo1.jpg", "category": "motorsport" },
    { "image_url": "https://example.com/photo2.jpg" },
    { "image_url": "https://example.com/photo3.jpg" }
  ],
  "options": { "enable_visual_matching": true }
}

// Response includes summary:
{
  "success": true,
  "results": [ ... ],
  "summary": { "total": 3, "successful": 3, "failed": 0 },
  "credits": { "consumed": 3, "remaining": 97 }
}
GET

/api/v1/results/:id

0 credits

Retrieve a previously completed analysis result by ID.

curl https://racetagger.cloud/api/v1/results/exec_abc123 \
  -H "Authorization: Bearer rt_live_your_key"
GET

/api/v1/usage

0 credits

Check credit balance and usage statistics.

// Response:
{
  "tier": "sandbox",
  "credits": {
    "limit": 100, "used": 15, "remaining": 85,
    "period_start": "2026-02-01T00:00:00Z",
    "period_end": "2026-03-01T00:00:00Z"
  },
  "rate_limit": { "requests_per_minute": 10 },
  "stats": {
    "total_requests": 42,
    "avg_processing_ms": 2100
  }
}

Error Handling

All errors include machine-readable codes and suggestions for self-correction:

{
  "success": false,
  "error": {
    "code": "credits_exhausted",
    "message": "No credits remaining.",
    "suggestion": "Upgrade your plan or wait for next billing period.",
    "docs_url": "https://racetagger.cloud/docs/api#errors"
  }
}
CodeStatusDescription
unauthorized401Invalid or missing API key
credits_exhausted402No credits remaining
rate_limited429Too many requests (includes Retry-After header)
bad_request400Invalid request parameters
image_required400No image provided
result_not_found404Analysis ID not found

Sport Categories

CategoryDescriptionDetects
motorsportF1, MotoGP, karting, rally, motocrossRace numbers, sponsors, livery
runningMarathons, trail running, cross countryBib numbers
cyclingRoad cycling, MTB, gran fondoJersey numbers, teams
streetStreet vehiclesLicense plates
aviationAircraftRegistration, airline, model

Pricing

Sandbox
Free
100/mo credits
10/min rate limit
Starter
€19/mo
2,000/mo credits
60/min rate limit
Pro
€49/mo
8,000/mo credits
120/min rate limit
Business
€99/mo
20,000/mo credits
200/min rate limit

Match endpoint is always free (0 credits). Enterprise plans available.

MCP Server (for AI Agents)

RaceTagger provides a Model Context Protocol (MCP) server for direct AI agent integration.

Remote endpoint: https://racetagger.cloud/mcp

Discovery: https://racetagger.cloud/.well-known/mcp.json

Compatible with: Claude Desktop, Cursor, Windsurf, and any MCP client

Available tools: racetagger_analyze, racetagger_match, racetagger_search, racetagger_export, racetagger_usage

OpenAPI Specification

Full machine-readable specification available at:

Download OpenAPI 3.1 YAML

Ready to integrate?

Get your API key and start analyzing race photos in minutes.

Request API Access