{
  "openapi" : "3.1.0",
  "tags" : [ {
    "name" : "api-keys",
    "description" : "Project-scoped API key lifecycle"
  }, {
    "name" : "auth",
    "description" : "Email + password authentication flow"
  }, {
    "name" : "exports",
    "description" : "JSON translation export"
  }, {
    "name" : "imports",
    "description" : "JSON translation import"
  }, {
    "name" : "keys",
    "description" : "Translation-key lifecycle"
  }, {
    "name" : "members",
    "description" : "Organization membership"
  }, {
    "name" : "meta",
    "description" : "Service metadata"
  }, {
    "name" : "namespaces",
    "description" : "Key namespace lifecycle"
  }, {
    "name" : "organizations",
    "description" : "Organization lifecycle"
  }, {
    "name" : "pats",
    "description" : "Personal Access Token lifecycle"
  }, {
    "name" : "projects",
    "description" : "Project lifecycle"
  } ],
  "components" : {
    "schemas" : {
      "CreateBody" : {
        "type" : "object",
        "properties" : {
          "keyName" : {
            "type" : [ "string", "null" ]
          },
          "namespaceSlug" : {
            "type" : [ "string", "null" ]
          },
          "description" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "CreateBody1" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "slug" : {
            "type" : [ "string", "null" ]
          },
          "description" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "CreateBody2" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "slug" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "CreateBody3" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "slug" : {
            "type" : [ "string", "null" ]
          },
          "description" : {
            "type" : [ "string", "null" ]
          },
          "baseLanguageTag" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "ForgotPasswordRequest" : {
        "type" : "object",
        "properties" : {
          "email" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "ImportBody" : {
        "type" : "object",
        "properties" : {
          "languageTag" : {
            "type" : [ "string", "null" ]
          },
          "namespaceSlug" : {
            "type" : [ "string", "null" ]
          },
          "mode" : {
            "type" : [ "string", "null" ]
          },
          "body" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "Index" : {
        "type" : "object",
        "required" : [ "name", "version", "docs", "health", "openapi", "swagger" ],
        "properties" : {
          "name" : {
            "type" : "string"
          },
          "version" : {
            "type" : "string"
          },
          "docs" : {
            "type" : "string"
          },
          "health" : {
            "type" : "string"
          },
          "openapi" : {
            "type" : "string"
          },
          "swagger" : {
            "type" : "string"
          }
        }
      },
      "LoginRequest" : {
        "type" : "object",
        "properties" : {
          "email" : {
            "type" : [ "string", "null" ]
          },
          "password" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "MintBody" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "scopes" : {
            "type" : [ "array", "null" ],
            "items" : {
              "type" : "string"
            }
          },
          "expiresAt" : {
            "type" : [ "string", "null" ],
            "format" : "date-time",
            "examples" : [ "2022-03-10T16:15:50Z" ]
          }
        }
      },
      "MintBody1" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "scopes" : {
            "type" : [ "array", "null" ],
            "items" : {
              "type" : "string"
            }
          },
          "expiresAt" : {
            "type" : [ "string", "null" ],
            "format" : "date-time",
            "examples" : [ "2022-03-10T16:15:50Z" ]
          }
        }
      },
      "RefreshRequest" : {
        "type" : "object",
        "properties" : {
          "refreshToken" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "ResetPasswordRequest" : {
        "type" : "object",
        "properties" : {
          "token" : {
            "type" : [ "string", "null" ]
          },
          "newPassword" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "SignupRequest" : {
        "type" : "object",
        "properties" : {
          "email" : {
            "type" : [ "string", "null" ]
          },
          "password" : {
            "type" : [ "string", "null" ]
          },
          "fullName" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "TokenRequest" : {
        "type" : "object",
        "properties" : {
          "token" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "TranslationBody" : {
        "type" : "object",
        "properties" : {
          "value" : {
            "type" : [ "string", "null" ]
          },
          "state" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "UpdateBody" : {
        "type" : "object",
        "properties" : {
          "keyName" : {
            "type" : [ "string", "null" ]
          },
          "namespaceSlug" : {
            "type" : [ "string", "null" ]
          },
          "description" : {
            "type" : [ "string", "null" ]
          },
          "state" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "UpdateBody1" : {
        "type" : "object",
        "properties" : {
          "role" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "UpdateBody2" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          }
        }
      },
      "UpdateBody3" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : [ "string", "null" ]
          },
          "description" : {
            "type" : [ "string", "null" ]
          }
        }
      }
    },
    "securitySchemes" : {
      "SecurityScheme" : {
        "type" : "http",
        "scheme" : "bearer",
        "bearerFormat" : "JWT",
        "description" : "Authentication"
      }
    }
  },
  "paths" : {
    "/" : {
      "get" : {
        "summary" : "Service metadata",
        "description" : "Returns name, version, and well-known endpoint paths.",
        "tags" : [ "meta" ],
        "responses" : {
          "200" : {
            "description" : "OK",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Index"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/forgot-password" : {
      "post" : {
        "summary" : "Request a password reset link. Always returns 202 — never leaks whether the email exists.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/ForgotPasswordRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "202" : {
            "description" : "Reset email queued if the account exists."
          },
          "400" : {
            "description" : "Validation failed."
          }
        }
      }
    },
    "/api/v1/auth/login" : {
      "post" : {
        "summary" : "Issue access + refresh tokens for a verified account.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/LoginRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Login successful."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Bad credentials."
          },
          "403" : {
            "description" : "Email not verified."
          }
        }
      }
    },
    "/api/v1/auth/refresh" : {
      "post" : {
        "summary" : "Rotate refresh tokens; single-use, replay returns 401.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/RefreshRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "New tokens issued."
          },
          "400" : {
            "description" : "Refresh token missing."
          },
          "401" : {
            "description" : "Refresh token invalid or reused."
          }
        }
      }
    },
    "/api/v1/auth/reset-password" : {
      "post" : {
        "summary" : "Consume a password-reset token and update the user's password.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/ResetPasswordRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Password updated."
          },
          "400" : {
            "description" : "Validation failed or token invalid."
          },
          "401" : {
            "description" : "Token expired."
          },
          "409" : {
            "description" : "Token already consumed."
          }
        }
      }
    },
    "/api/v1/auth/signup" : {
      "post" : {
        "summary" : "Create a new account; sends a verification email.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/SignupRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Account created; verification email sent."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "409" : {
            "description" : "Email already registered."
          }
        }
      }
    },
    "/api/v1/auth/verify-email" : {
      "post" : {
        "summary" : "Consume a verification token and flip emailVerifiedAt.",
        "tags" : [ "auth" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/TokenRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Email verified."
          },
          "400" : {
            "description" : "Token invalid."
          },
          "401" : {
            "description" : "Token expired."
          },
          "409" : {
            "description" : "Token already consumed."
          }
        }
      }
    },
    "/api/v1/organizations" : {
      "get" : {
        "summary" : "List organizations the caller is a member of.",
        "tags" : [ "organizations" ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "post" : {
        "summary" : "Create a new organization; caller becomes OWNER.",
        "tags" : [ "organizations" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/CreateBody2"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Organization created."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "409" : {
            "description" : "Slug already in use."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}" : {
      "patch" : {
        "summary" : "Rename an organization (name only for v0.1.0).",
        "tags" : [ "organizations" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/UpdateBody2"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Updated."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "get" : {
        "summary" : "Fetch one organization the caller belongs to.",
        "tags" : [ "organizations" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Found."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/members" : {
      "get" : {
        "summary" : "List members of the organization.",
        "tags" : [ "members" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Caller is not a member of this org."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/members/{userId}" : {
      "patch" : {
        "summary" : "Change a member's role.",
        "tags" : [ "members" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "userId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/UpdateBody1"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Role updated."
          },
          "400" : {
            "description" : "Invalid role."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Member not found."
          },
          "409" : {
            "description" : "Would leave the org with no OWNER."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "delete" : {
        "summary" : "Remove a member from the organization.",
        "tags" : [ "members" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "userId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "204" : {
            "description" : "Removed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Member not found."
          },
          "409" : {
            "description" : "Would leave the org with no OWNER."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects" : {
      "get" : {
        "summary" : "List every project in the organization.",
        "tags" : [ "projects" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "post" : {
        "summary" : "Create a project inside the organization.",
        "tags" : [ "projects" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/CreateBody3"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Project created."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Caller is not a member."
          },
          "409" : {
            "description" : "Slug already in use."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}" : {
      "patch" : {
        "summary" : "Update name or description.",
        "tags" : [ "projects" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/UpdateBody3"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Updated."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "get" : {
        "summary" : "Fetch one project.",
        "tags" : [ "projects" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Found."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/exports/json" : {
      "get" : {
        "summary" : "Export i18next JSON translations for one language tag.",
        "tags" : [ "exports" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "languageTag",
          "in" : "query",
          "schema" : {
            "type" : [ "string", "null" ]
          }
        }, {
          "name" : "minState",
          "in" : "query",
          "schema" : {
            "type" : [ "string", "null" ]
          }
        }, {
          "name" : "namespaceSlug",
          "in" : "query",
          "schema" : {
            "type" : [ "string", "null" ]
          }
        }, {
          "name" : "shape",
          "in" : "query",
          "schema" : {
            "type" : "string",
            "default" : "FLAT"
          },
          "required" : true
        }, {
          "name" : "tags",
          "in" : "query",
          "schema" : {
            "type" : [ "string", "null" ]
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Export generated. Body is the JSON file."
          },
          "400" : {
            "description" : "Validation failed (missing language tag, bad shape, bad state)."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Project not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/imports/json" : {
      "post" : {
        "summary" : "Import i18next flat/nested JSON translations into a project for one language.",
        "tags" : [ "imports" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/ImportBody"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Import finished. Summary in body."
          },
          "400" : {
            "description" : "Validation failed — bad JSON, unsupported type, missing language tag."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Project / language not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/keys" : {
      "get" : {
        "summary" : "List keys in the project.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "limit",
          "in" : "query",
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "default" : 50
          }
        }, {
          "name" : "namespace",
          "in" : "query",
          "schema" : {
            "type" : [ "string", "null" ]
          }
        }, {
          "name" : "offset",
          "in" : "query",
          "schema" : {
            "type" : "integer",
            "format" : "int32",
            "default" : 0
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "post" : {
        "summary" : "Create a key inside a namespace.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/CreateBody"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Key created."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Project / namespace not found or caller is not a member."
          },
          "409" : {
            "description" : "Key name already exists in the namespace."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/keys/{keyId}" : {
      "patch" : {
        "summary" : "Rename, reclassify, or re-state a key.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "keyId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/UpdateBody"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Updated."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "get" : {
        "summary" : "Fetch one key with its translations.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "keyId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Found."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "delete" : {
        "summary" : "Soft-delete a key. Idempotent.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "keyId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "204" : {
            "description" : "Deleted."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/keys/{keyId}/translations/{languageTag}" : {
      "put" : {
        "summary" : "Upsert one translation cell for a key.",
        "tags" : [ "keys" ],
        "parameters" : [ {
          "name" : "keyId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "languageTag",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/TranslationBody"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Upserted."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Not found or caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/organizations/{orgSlug}/projects/{projectSlug}/namespaces" : {
      "get" : {
        "summary" : "List namespaces in the project.",
        "tags" : [ "namespaces" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Caller is not a member."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "post" : {
        "summary" : "Create a namespace in the project.",
        "tags" : [ "namespaces" ],
        "parameters" : [ {
          "name" : "orgSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectSlug",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/CreateBody1"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "Namespace created."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "401" : {
            "description" : "Not authenticated."
          },
          "404" : {
            "description" : "Project not found or caller is not a member."
          },
          "409" : {
            "description" : "Slug already in use in this project."
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/projects/{projectId}/api-keys" : {
      "post" : {
        "summary" : "Mint a new API key. The full secret is returned exactly once.",
        "description" : "Scopes requested on the new key must be a subset of the caller's current scope set; otherwise 403 SCOPE_ESCALATION. The returned `secret` is the full token to present as `Authorization: ApiKey <secret>` on future requests.",
        "tags" : [ "api-keys" ],
        "parameters" : [ {
          "name" : "projectId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/MintBody"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "API key minted; secret in body."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "403" : {
            "description" : "Scope escalation attempt."
          },
          "404" : {
            "description" : "Project not found."
          },
          "401" : {
            "description" : "Not Authorized"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "get" : {
        "summary" : "List API keys for the project (no secrets).",
        "tags" : [ "api-keys" ],
        "parameters" : [ {
          "name" : "projectId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "404" : {
            "description" : "Project not found."
          },
          "401" : {
            "description" : "Not Authorized"
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/projects/{projectId}/api-keys/{apiKeyId}" : {
      "delete" : {
        "summary" : "Revoke an API key. Idempotent.",
        "tags" : [ "api-keys" ],
        "parameters" : [ {
          "name" : "apiKeyId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "projectId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "204" : {
            "description" : "Key revoked."
          },
          "404" : {
            "description" : "Project or API key not found."
          },
          "401" : {
            "description" : "Not Authorized"
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/users/me/pats" : {
      "post" : {
        "summary" : "Mint a new PAT. The full secret is returned exactly once.",
        "description" : "Scopes requested on the new PAT must be a subset of the caller's current JWT scope set.",
        "tags" : [ "pats" ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/MintBody1"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "201" : {
            "description" : "PAT minted; secret in body."
          },
          "400" : {
            "description" : "Validation failed."
          },
          "403" : {
            "description" : "Scope escalation attempt."
          },
          "401" : {
            "description" : "Not Authorized"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      },
      "get" : {
        "summary" : "List PATs owned by the caller (no secrets).",
        "tags" : [ "pats" ],
        "responses" : {
          "200" : {
            "description" : "Listing returned."
          },
          "401" : {
            "description" : "Not Authorized"
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    },
    "/api/v1/users/me/pats/{patId}" : {
      "delete" : {
        "summary" : "Revoke a PAT owned by the caller. Idempotent.",
        "tags" : [ "pats" ],
        "parameters" : [ {
          "name" : "patId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "204" : {
            "description" : "PAT revoked."
          },
          "404" : {
            "description" : "PAT not found."
          },
          "401" : {
            "description" : "Not Authorized"
          },
          "403" : {
            "description" : "Not Allowed"
          }
        },
        "security" : [ {
          "SecurityScheme" : [ ]
        } ]
      }
    }
  },
  "info" : {
    "title" : "Translately API",
    "version" : "0.0.1-SNAPSHOT",
    "description" : "Open-source self-hosted localization and translation management API.",
    "contact" : {
      "name" : "Pratiyush",
      "url" : "https://github.com/Pratiyush/translately"
    },
    "license" : {
      "name" : "MIT",
      "url" : "https://opensource.org/licenses/MIT"
    }
  },
  "servers" : [ {
    "url" : "http://localhost:8080",
    "description" : "Auto generated value"
  }, {
    "url" : "http://0.0.0.0:8080",
    "description" : "Auto generated value"
  } ]
}