{
  "openapi": "3.1.0",
  "info": {
    "title": "Outlap Track API",
    "version": "1.0.0",
    "description": "Read-only access to a track's calendar, entries and payouts. Amounts are integer minor units.",
    "contact": {
      "name": "Outlap support",
      "email": "support@outlap.xyz"
    }
  },
  "externalDocs": {
    "description": "Documentation",
    "url": "https://docs.outlap.xyz/api/overview"
  },
  "servers": [
    {
      "url": "https://fzfstcyowovukscxgdrh.supabase.co/functions/v1/track-api",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/summary": {
      "get": {
        "operationId": "getSummary",
        "summary": "Track summary and season totals",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/summary"
        },
        "responses": {
          "200": {
            "description": "Summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "track": {
                      "$ref": "#/components/schemas/Track"
                    },
                    "upcoming_events": {
                      "type": "integer"
                    },
                    "upcoming_entries": {
                      "type": "integer"
                    },
                    "next_event": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "date": {
                              "type": "string",
                              "format": "date"
                            },
                            "entries": {
                              "type": "integer"
                            },
                            "capacity": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            }
                          }
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "revenue": {
                      "$ref": "#/components/schemas/Revenue"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "listEvents",
        "summary": "Calendar with entry counts",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/events"
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Earliest event date. Default today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Latest event date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "track": {
                      "$ref": "#/components/schemas/Track"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/{eventId}/entries": {
      "get": {
        "operationId": "listEntries",
        "summary": "Entry list for an event",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/entries"
        },
        "parameters": [
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "event": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "date": {
                          "type": "string",
                          "format": "date"
                        }
                      }
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entry"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Event not found for this track.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payouts": {
      "get": {
        "operationId": "getPayouts",
        "summary": "Payout report per event",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/payouts"
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Orders created on or after.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Orders created on or before.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payout lines.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "track": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "platform_fee_rate": {
                      "type": "number",
                      "examples": [
                        0.05
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "lines": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PayoutLine"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/calendar.ics": {
      "get": {
        "operationId": "getCalendar",
        "summary": "Subscribable ICS calendar (published events)",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/calendar"
        },
        "description": "Also accepts the key as `?key=` for calendar clients that cannot send headers.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "queryKey": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Earliest event date. Default 90 days ago.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "iCalendar feed.",
            "content": {
              "text/calendar": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/public/{club}/calendar.ics": {
      "get": {
        "operationId": "getPublicCalendar",
        "summary": "Public ICS feed (no key)",
        "externalDocs": {
          "description": "Documentation",
          "url": "https://docs.outlap.xyz/api/track/public-calendar"
        },
        "security": [],
        "parameters": [
          {
            "name": "club",
            "in": "path",
            "required": true,
            "description": "Club slug or UUID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "iCalendar feed of published, public events.",
            "content": {
              "text/calendar": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Club API key beginning `olap_`. Shown once when created."
      },
      "queryKey": {
        "type": "apiKey",
        "in": "query",
        "name": "key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "examples": [
              "invalid api key"
            ]
          }
        },
        "additionalProperties": true
      },
      "RateLimit": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "const": "rate limit exceeded"
          },
          "scope": {
            "type": "string",
            "enum": [
              "minute",
              "hour"
            ]
          },
          "retry_after_s": {
            "type": "integer"
          }
        }
      },
      "Track": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Revenue": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "examples": [
              "eur"
            ]
          },
          "gross_minor": {
            "type": "integer"
          },
          "refunded_minor": {
            "type": "integer"
          },
          "net_minor": {
            "type": "integer"
          },
          "platform_fee_minor": {
            "type": "integer"
          },
          "estimated_payout_minor": {
            "type": "integer",
            "description": "Net minus platform fee. Excludes Stripe processing fees."
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "start_time": {
            "type": [
              "string",
              "null"
            ]
          },
          "end_time": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "published": {
            "type": "boolean"
          },
          "visibility": {
            "type": "string"
          },
          "capacity": {
            "type": [
              "integer",
              "null"
            ]
          },
          "entries": {
            "type": "integer"
          },
          "price_amount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "currency": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        }
      },
      "Entry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "car": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "group_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "registered_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PayoutLine": {
        "type": "object",
        "properties": {
          "event_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "event_name": {
            "type": "string"
          },
          "event_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "currency": {
            "type": "string"
          },
          "orders": {
            "type": "integer"
          },
          "gross_minor": {
            "type": "integer"
          },
          "refunded_minor": {
            "type": "integer"
          },
          "net_minor": {
            "type": "integer"
          },
          "platform_fee_minor": {
            "type": "integer"
          },
          "estimated_payout_minor": {
            "type": "integer"
          }
        }
      }
    }
  }
}
