{
  "openapi": "3.1.0",
  "info": {
    "title": "WorkoutDB API",
    "version": "1.0.0",
    "description": "The exercise database API, done right — combinable filters, ranked fuzzy + full-text search, and English/Spanish content."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "components": {
    "schemas": {
      "ExerciseListEnvelope": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Exercise"
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "lang": {
                "type": "string",
                "enum": [
                  "en",
                  "es"
                ]
              },
              "pagination": {
                "type": "object",
                "properties": {
                  "offset": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "total": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "nextCursor": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "offset",
                  "limit",
                  "total",
                  "nextCursor"
                ]
              }
            },
            "required": [
              "lang",
              "pagination"
            ]
          },
          "requestId": {
            "type": "string"
          }
        },
        "required": [
          "data",
          "meta",
          "requestId"
        ]
      },
      "Exercise": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "bodyPart": {
            "type": "string"
          },
          "target": {
            "type": "string"
          },
          "secondaryMuscles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "equipment": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "strength",
              "cardio",
              "mobility",
              "stretching",
              "plyometrics"
            ]
          },
          "difficulty": {
            "type": "string",
            "enum": [
              "beginner",
              "intermediate",
              "advanced"
            ]
          },
          "force": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "push",
              "pull",
              "static",
              null
            ]
          },
          "mechanic": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "compound",
              "isolation",
              null
            ]
          },
          "description": {
            "type": "string"
          },
          "instructions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "gifUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "media": {
            "type": "object",
            "properties": {
              "video": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "mp4": {
                    "type": "object",
                    "properties": {
                      "480p": {
                        "type": "string",
                        "format": "uri"
                      },
                      "720p": {
                        "type": "string",
                        "format": "uri"
                      }
                    }
                  },
                  "webm": {
                    "type": "object",
                    "properties": {
                      "720p": {
                        "type": "string",
                        "format": "uri"
                      }
                    }
                  },
                  "poster": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "mp4",
                  "webm",
                  "poster"
                ]
              },
              "gif": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri"
              },
              "photos": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              }
            },
            "required": [
              "video",
              "gif",
              "photos"
            ]
          }
        },
        "required": [
          "id",
          "slug",
          "name",
          "bodyPart",
          "target",
          "secondaryMuscles",
          "equipment",
          "category",
          "difficulty",
          "force",
          "mechanic",
          "description",
          "instructions",
          "gifUrl",
          "media"
        ]
      },
      "ExerciseEnvelope": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Exercise"
          },
          "meta": {
            "type": "object",
            "properties": {
              "lang": {
                "type": "string",
                "enum": [
                  "en",
                  "es"
                ]
              }
            },
            "required": [
              "lang"
            ]
          },
          "requestId": {
            "type": "string"
          }
        },
        "required": [
          "data",
          "meta",
          "requestId"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/exercises/search": {
      "get": {
        "tags": [
          "Exercises"
        ],
        "summary": "Ranked search (trigram similarity + full-text rank, accent-insensitive)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "bodyPart",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "target",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "equipment",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "muscle",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "strength",
                "cardio",
                "mobility",
                "stretching",
                "plyometrics"
              ]
            },
            "required": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "beginner",
                "intermediate",
                "advanced"
              ]
            },
            "required": false,
            "name": "difficulty",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "push",
                "pull",
                "static"
              ]
            },
            "required": false,
            "name": "force",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "compound",
                "isolation"
              ]
            },
            "required": false,
            "name": "mechanic",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": true,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "difficulty"
              ],
              "default": "name"
            },
            "required": false,
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "asc"
            },
            "required": false,
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es"
              ]
            },
            "required": false,
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Exercise list envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExerciseListEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (error envelope)"
          }
        }
      }
    },
    "/v1/exercises": {
      "get": {
        "tags": [
          "Exercises"
        ],
        "summary": "List/filter exercises (combinable query params)",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "bodyPart",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "target",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "equipment",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "muscle",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "strength",
                "cardio",
                "mobility",
                "stretching",
                "plyometrics"
              ]
            },
            "required": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "beginner",
                "intermediate",
                "advanced"
              ]
            },
            "required": false,
            "name": "difficulty",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "push",
                "pull",
                "static"
              ]
            },
            "required": false,
            "name": "force",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "compound",
                "isolation"
              ]
            },
            "required": false,
            "name": "mechanic",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "difficulty"
              ],
              "default": "name"
            },
            "required": false,
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "asc"
            },
            "required": false,
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "integer",
                "null"
              ],
              "minimum": 0,
              "default": 0
            },
            "required": false,
            "name": "offset",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es"
              ]
            },
            "required": false,
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Exercise list envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExerciseListEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (error envelope)"
          }
        }
      }
    },
    "/v1/exercises/{idOrSlug}": {
      "get": {
        "tags": [
          "Exercises"
        ],
        "summary": "Get one exercise by cuid or slug",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "required": true,
            "name": "idOrSlug",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es"
              ]
            },
            "required": false,
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Exercise envelope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExerciseEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Not found (error envelope)"
          }
        }
      }
    },
    "/v1/bodyparts": {
      "get": {
        "tags": [
          "Taxonomies"
        ],
        "summary": "List body parts (localized)",
        "responses": {
          "200": {
            "description": "Localized {slug,name} list envelope"
          }
        }
      }
    },
    "/v1/muscles": {
      "get": {
        "tags": [
          "Taxonomies"
        ],
        "summary": "List muscles (localized)",
        "responses": {
          "200": {
            "description": "Localized {slug,name} list envelope"
          }
        }
      }
    },
    "/v1/equipment": {
      "get": {
        "tags": [
          "Taxonomies"
        ],
        "summary": "List equipment (localized)",
        "responses": {
          "200": {
            "description": "Localized {slug,name} list envelope"
          }
        }
      }
    },
    "/v1/categories": {
      "get": {
        "tags": [
          "Taxonomies"
        ],
        "summary": "List categories (localized)",
        "responses": {
          "200": {
            "description": "Localized {slug,name} list envelope"
          }
        }
      }
    },
    "/v1/meta": {
      "get": {
        "tags": [
          "Taxonomies"
        ],
        "summary": "Counts + every filterable value in one call (app-bootstrap friendly)",
        "responses": {
          "200": {
            "description": "Meta envelope"
          }
        }
      }
    }
  },
  "webhooks": {}
}
