Docs/RaceTagger API

RaceTagger API

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

v1 — Stable · Base 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.

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"
  }
}
Code Status Description
unauthorized 401 Invalid or missing API key
credits_exhausted 402 No credits remaining
rate_limited 429 Too many requests (includes Retry-After header)
bad_request 400 Invalid request parameters
image_required 400 No image provided
result_not_found 404 Analysis ID not found

Sport Categories

Category Description Detects
motorsport F1, MotoGP, karting, rally, motocross Race numbers, sponsors, livery
running Marathons, trail running, cross country Bib numbers
cycling Road cycling, MTB, gran fondo Jersey numbers, teams
street Street vehicles License plates
aviation Aircraft Registration, airline, model

Pricing

Tier Price Credits Rate Limit
Sandbox Free 100/mo 10/min
Starter €19/mo 2,000/mo 60/min
Pro €49/mo 8,000/mo 120/min
Business €99/mo 20,000/mo 200/min

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. OpenAPI 3.1 YAML — Coming Soon.

Ready to integrate?

Get your API key and start analyzing race photos in minutes. [Request API Access](/api-access)