{
  "openapi": "3.1.0",
  "info": {
    "title": "GTA API",
    "version": "1.0",
    "description": "A Grand Theft Auto–flavoured sandbox: browse Los Santos characters and vehicles, respray cars at a Pay-n-Spray, buy weapons from the catalogue, start missions with prerequisites, plan authenticated heists, run a slow (~2s) police chase that inflates your wanted level (0–5 stars) and bribe the LSPD to clear it. Cash starts at $5000 and 402 fires when you are broke."
  },
  "servers": [
    {
      "url": "https://funapi.dev/api/gta/v1"
    }
  ],
  "tags": [
    {
      "name": "characters",
      "description": "heroes and contacts"
    },
    {
      "name": "vehicles",
      "description": "cars and Pay-n-Spray"
    },
    {
      "name": "weapons",
      "description": "the ammu-nation catalogue"
    },
    {
      "name": "missions",
      "description": "story jobs with prereqs"
    },
    {
      "name": "wanted",
      "description": "stars, bribes and police chases"
    },
    {
      "name": "radio",
      "description": "in-game stations"
    }
  ],
  "paths": {
    "/characters": {
      "get": {
        "tags": [
          "characters"
        ],
        "summary": "List characters (filter by city or affiliation)",
        "operationId": "gta-characters",
        "responses": {
          "200": {
            "description": "Character list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Vice City"
          },
          {
            "name": "affiliation",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Vercetti Gang"
          }
        ]
      }
    },
    "/characters/{id}": {
      "get": {
        "tags": [
          "characters"
        ],
        "summary": "Get one character",
        "operationId": "gta-character",
        "responses": {
          "200": {
            "description": "Character",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown character",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 4
          }
        ]
      }
    },
    "/vehicles": {
      "get": {
        "tags": [
          "vehicles"
        ],
        "summary": "List vehicles (filter by class)",
        "operationId": "gta-vehicles",
        "responses": {
          "200": {
            "description": "Vehicles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "class",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "sports"
          }
        ]
      }
    },
    "/vehicles/{id}": {
      "get": {
        "tags": [
          "vehicles"
        ],
        "summary": "Get one vehicle",
        "operationId": "gta-vehicle",
        "responses": {
          "200": {
            "description": "Vehicle",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown vehicle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 3
          }
        ]
      }
    },
    "/vehicles/{id}/respray": {
      "post": {
        "tags": [
          "vehicles"
        ],
        "summary": "Respray a vehicle at Pay-n-Spray — spends cash (402 when broke)",
        "operationId": "gta-respray",
        "responses": {
          "200": {
            "description": "Respray done",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "402": {
            "description": "Not enough cash",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown vehicle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Missing color",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "color": {
                    "type": "string"
                  }
                },
                "required": [
                  "color"
                ],
                "additionalProperties": false
              },
              "example": {
                "color": "matte black"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/weapons": {
      "get": {
        "tags": [
          "weapons"
        ],
        "summary": "Browse the ammu-nation catalogue (filter by category)",
        "operationId": "gta-weapons",
        "responses": {
          "200": {
            "description": "Weapons",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "automatic"
          }
        ]
      }
    },
    "/weapons/{id}/buy": {
      "post": {
        "tags": [
          "weapons"
        ],
        "summary": "Buy a weapon — spends cash (402 when broke, 409 if already owned)",
        "operationId": "gta-weapon-buy",
        "responses": {
          "200": {
            "description": "Weapon purchased",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "402": {
            "description": "Not enough cash",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown weapon",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already owned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 3
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/missions": {
      "get": {
        "tags": [
          "missions"
        ],
        "summary": "List missions (filter by status or city)",
        "operationId": "gta-missions",
        "responses": {
          "200": {
            "description": "Missions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "available"
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Los Santos"
          }
        ]
      }
    },
    "/missions/{id}": {
      "get": {
        "tags": [
          "missions"
        ],
        "summary": "Get one mission with its prereq",
        "operationId": "gta-mission",
        "responses": {
          "200": {
            "description": "Mission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown mission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 2
          }
        ]
      }
    },
    "/missions/{id}/start": {
      "post": {
        "tags": [
          "missions"
        ],
        "summary": "Start a mission (409 if one is active, 422 if prereq not completed)",
        "operationId": "gta-mission-start",
        "responses": {
          "200": {
            "description": "Mission started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown mission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "A mission is already active",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Prerequisite not completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/missions/{id}/complete": {
      "post": {
        "tags": [
          "missions"
        ],
        "summary": "Complete the active mission — pays out the reward",
        "operationId": "gta-mission-complete",
        "responses": {
          "200": {
            "description": "Mission completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown mission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Not the active mission",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "gta-mission-1"
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/heists": {
      "post": {
        "tags": [
          "missions"
        ],
        "summary": "Plan a heist — choose an approach (admin only)",
        "operationId": "gta-heist-plan",
        "responses": {
          "201": {
            "description": "Heist planned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri-reference"
                }
              }
            }
          },
          "422": {
            "description": "Invalid approach or crew size",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "gta-heist-1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "approach": {
                    "type": "string"
                  },
                  "crewSize": {
                    "type": "integer"
                  }
                },
                "required": [
                  "name",
                  "approach",
                  "crewSize"
                ],
                "additionalProperties": false
              },
              "example": {
                "name": "The Jewelry Store Job",
                "approach": "stealth",
                "crewSize": 3
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/heists/{id}": {
      "get": {
        "tags": [
          "missions"
        ],
        "summary": "Get a planned heist",
        "operationId": "gta-heist",
        "responses": {
          "200": {
            "description": "Heist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Unknown heist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 1
          }
        ]
      }
    },
    "/wanted": {
      "get": {
        "tags": [
          "wanted"
        ],
        "summary": "Current wanted level (0–5 stars)",
        "operationId": "gta-wanted",
        "responses": {
          "200": {
            "description": "Wanted level",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "wanted"
        ],
        "summary": "Bribe the LSPD to clear wanted level — costs $1000/star (402 when broke)",
        "operationId": "gta-wanted-clear",
        "responses": {
          "200": {
            "description": "Wanted cleared",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "402": {
            "description": "Not enough cash",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already clean",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/wanted/increase": {
      "post": {
        "tags": [
          "wanted"
        ],
        "summary": "Commit a crime — inflates wanted level after a ~2s police chase",
        "operationId": "gta-wanted-increase",
        "responses": {
          "200": {
            "description": "Wanted increased",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "409": {
            "description": "Already at max stars",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/radio": {
      "get": {
        "tags": [
          "radio"
        ],
        "summary": "List in-game radio stations",
        "operationId": "gta-radio",
        "responses": {
          "200": {
            "description": "Stations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Use qa-admin-token / qa-viewer-token, or a JWT from POST /auth/v1/login."
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Cargo demo key: cargo-key-123."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    }
  }
}
