Files
trailbase/docs/openapi/schema.json
2025-10-07 21:51:01 +02:00

979 lines
25 KiB
JSON

{
"openapi": "3.1.0",
"info": {
"title": "TrailBase",
"description": "TrailBase APIs",
"license": {
"name": "OSL-3.0",
"identifier": "OSL-3.0"
},
"version": "0.2.0"
},
"paths": {
"/api/auth/v1/avatar/": {
"post": {
"tags": ["auth"],
"operationId": "create_avatar_handler",
"responses": {
"200": {
"description": "Deletion success"
}
}
},
"delete": {
"tags": ["auth"],
"operationId": "delete_avatar_handler",
"responses": {
"200": {
"description": "Deletion success"
}
}
}
},
"/api/auth/v1/avatar/:b64_user_id": {
"get": {
"tags": ["auth"],
"operationId": "get_avatar_handler",
"responses": {
"200": {
"description": "Optional Avatar file"
}
}
}
},
"/api/auth/v1/change_email/confirm/:email_verification_code": {
"get": {
"tags": ["auth"],
"summary": "Confirm a change of email address.",
"operationId": "change_email_confirm_handler",
"responses": {
"200": {
"description": "Success."
}
}
}
},
"/api/auth/v1/change_email/request": {
"post": {
"tags": ["auth"],
"summary": "Request an email change.",
"operationId": "change_email_request_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChangeEmailRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Success."
}
}
}
},
"/api/auth/v1/change_password": {
"post": {
"tags": ["auth"],
"summary": "Request a change of password.",
"operationId": "change_password_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChangePasswordRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Success."
}
}
}
},
"/api/auth/v1/delete": {
"delete": {
"tags": ["auth"],
"summary": "Get public profile of the given user.",
"operationId": "delete_handler",
"responses": {
"200": {
"description": "User deleted."
}
}
}
},
"/api/auth/v1/login": {
"post": {
"tags": ["auth"],
"summary": "Log in users by email and password.",
"operationId": "login_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "response_type",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "pkce_code_challenge",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Auth & refresh tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginResponse"
}
}
}
}
}
}
},
"/api/auth/v1/logout": {
"get": {
"tags": ["auth"],
"summary": "Logs out the current user and delete **all** pending sessions for that user.",
"description": "Relies on the client to drop any auth tokens. We delete the session to avoid refresh tokens\nbringing a logged out session back to live.",
"operationId": "logout_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"responses": {
"200": {
"description": "Auth & refresh tokens."
}
}
},
"post": {
"tags": ["auth"],
"summary": "Logs out the current user and deletes the specific session for the given refresh token.",
"description": "Relies on the client to drop any auth tokens.",
"operationId": "post_logout_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LogoutRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Auth & refresh tokens."
}
}
}
},
"/api/auth/v1/oauth/providers": {
"get": {
"tags": ["oauth"],
"summary": "List configured OAuth providers.",
"operationId": "list_configured_providers_handler",
"responses": {
"200": {
"description": "List of OAuth providers.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ConfiguredOAuthProvidersResponse"
}
}
}
}
}
}
},
"/api/auth/v1/oauth/{provider}/callback": {
"get": {
"tags": ["oauth"],
"summary": "This handler receives the ?code=<>&state=<>, uses it to get an external oauth token, gets the\nuser's information, creates a new local user if needed, and finally mints our own tokens.",
"operationId": "callback_from_external_auth_provider",
"parameters": [
{
"name": "code",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "state",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "provider",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Redirect."
}
}
}
},
"/api/auth/v1/oauth/{provider}/login": {
"get": {
"tags": ["oauth"],
"summary": "Log in via external OAuth provider.",
"operationId": "login_with_external_auth_provider",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "response_type",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "pkce_code_challenge",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "provider",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Redirect."
}
}
}
},
"/api/auth/v1/refresh": {
"post": {
"tags": ["auth"],
"summary": "Refreshes auth tokens given a refresh token.",
"description": "NOTE: This is a json-only API, since cookies will be auto-refreshed.",
"operationId": "refresh_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefreshRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Refreshed auth tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefreshResponse"
}
}
}
}
}
}
},
"/api/auth/v1/register": {
"post": {
"tags": ["auth"],
"summary": "Registers a new user with email and password.",
"operationId": "register_user_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RegisterUserRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful registration."
}
}
}
},
"/api/auth/v1/reset_password/request": {
"post": {
"tags": ["auth"],
"summary": "Request a password reset.",
"operationId": "reset_password_request_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResetPasswordRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Success."
}
}
}
},
"/api/auth/v1/reset_password/update/:password_reset_code": {
"post": {
"tags": ["auth"],
"summary": "Endpoint for setting a new password after the user has requested a reset and provided a\nreplacement password.",
"operationId": "reset_password_update_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResetPasswordUpdateRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Success."
}
}
}
},
"/api/auth/v1/status": {
"get": {
"tags": ["auth"],
"summary": "Check login status.",
"operationId": "login_status_handler",
"responses": {
"200": {
"description": "Auth & refresh tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginStatusResponse"
}
}
}
}
}
}
},
"/api/auth/v1/token": {
"post": {
"tags": ["auth"],
"summary": "Exchange authorization code for auth tokens.",
"description": "This API endpoint is meant for client-side applications (SPA, mobile, desktop, ...) using the\nweb-auth flow.",
"operationId": "auth_code_to_token_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthCodeToTokenRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Converts auth & pkce codes to tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenResponse"
}
}
}
}
}
}
},
"/api/auth/v1/verify_email/confirm/:email_verification_code": {
"get": {
"tags": ["auth"],
"summary": "Request a new email to verify email address.",
"operationId": "verify_email_handler",
"responses": {
"200": {
"description": "Email verified."
}
}
}
},
"/api/auth/v1/verify_email/trigger": {
"get": {
"tags": ["auth"],
"summary": "Request a new email to verify email address.",
"operationId": "request_email_verification_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmailVerificationRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Email verification sent."
}
}
}
},
"/api/records/v1/{name}": {
"get": {
"tags": ["records"],
"summary": "Lists records matching the given filters",
"operationId": "list_records_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Matching records."
}
}
},
"post": {
"tags": ["records"],
"summary": "Create new record.",
"operationId": "create_record_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"description": "Redirect user to this address upon successful record creation.\nThis only exists to support insertions via static HTML form actions.\n\nWe may want to have a different on-error redirect to better support the static HTML use-case.",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {}
}
},
"required": true
},
"responses": {
"200": {
"description": "Ids of successfully created records.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateRecordResponse"
}
}
}
}
}
}
},
"/api/records/v1/{name}/schema": {
"get": {
"tags": ["records"],
"summary": "Retrieve json schema associated with given record api.",
"operationId": "json_schema_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "JSON schema."
}
}
}
},
"/api/records/v1/{name}/subscribe/{record}": {
"get": {
"tags": ["records"],
"summary": "Read record.",
"operationId": "add_subscription_sse_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "record",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "SSE stream of record changes."
}
}
}
},
"/api/records/v1/{name}/{record}": {
"get": {
"tags": ["records"],
"summary": "Read record.",
"operationId": "read_record_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "record",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Record contents.",
"content": {
"application/json": {
"schema": {}
}
}
}
}
},
"delete": {
"tags": ["records"],
"summary": "Delete record.",
"operationId": "delete_record_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "record",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful deletion."
}
}
},
"patch": {
"tags": ["records"],
"summary": "Update existing record.",
"operationId": "update_record_handler",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "record",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful update."
}
}
}
},
"/api/records/v1/{name}/{record}/file/{column_name}": {
"get": {
"tags": ["records"],
"summary": "Read file associated with record.",
"description": "You may prefer using the more general \"files\" (plural) handler below. Since using unique\nfilenames does help with the content lifecycle, such as caching.",
"operationId": "get_uploaded_file_from_record_handler",
"responses": {
"200": {
"description": "File contents."
}
}
}
},
"/api/records/v1/{name}/{record}/files/{column_name}/{file_name}": {
"get": {
"tags": ["records"],
"summary": "Read single file from list associated with record.",
"operationId": "get_uploaded_files_from_record_handler",
"responses": {
"200": {
"description": "File contents."
}
}
}
}
},
"components": {
"schemas": {
"AuthCodeToTokenRequest": {
"type": "object",
"properties": {
"authorization_code": {
"type": ["string", "null"]
},
"pkce_code_verifier": {
"type": ["string", "null"]
}
}
},
"ChangeEmailRequest": {
"type": "object",
"required": ["csrf_token", "new_email"],
"properties": {
"csrf_token": {
"type": "string"
},
"new_email": {
"type": "string"
},
"old_email": {
"type": ["string", "null"]
}
}
},
"ChangePasswordRequest": {
"type": "object",
"required": ["old_password", "new_password", "new_password_repeat"],
"properties": {
"new_password": {
"type": "string"
},
"new_password_repeat": {
"type": "string"
},
"old_password": {
"type": "string"
}
}
},
"ConfiguredOAuthProvidersResponse": {
"type": "object",
"required": ["providers"],
"properties": {
"providers": {
"type": "array",
"items": {
"type": "array",
"items": false,
"prefixItems": [
{
"type": "string"
},
{
"type": "string"
}
]
},
"description": "List of tuples (<name>, <display_name>)."
}
}
},
"CreateRecordResponse": {
"type": "object",
"required": ["ids"],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Url-Safe base64 encoded ids of the newly created record."
}
}
},
"EmailVerificationRequest": {
"type": "object",
"required": ["email"],
"properties": {
"email": {
"type": "string"
}
}
},
"LoginRequest": {
"type": "object",
"required": ["email", "password"],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"pkce_code_challenge": {
"type": ["string", "null"]
},
"redirect_uri": {
"type": ["string", "null"]
},
"response_type": {
"type": ["string", "null"]
}
}
},
"LoginResponse": {
"type": "object",
"required": ["auth_token", "refresh_token", "csrf_token"],
"properties": {
"auth_token": {
"type": "string"
},
"csrf_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
}
}
},
"LoginStatusResponse": {
"type": "object",
"properties": {
"auth_token": {
"type": ["string", "null"]
},
"csrf_token": {
"type": ["string", "null"]
},
"refresh_token": {
"type": ["string", "null"]
}
}
},
"LogoutRequest": {
"type": "object",
"required": ["refresh_token"],
"properties": {
"refresh_token": {
"type": "string"
}
}
},
"RefreshRequest": {
"type": "object",
"required": ["refresh_token"],
"properties": {
"refresh_token": {
"type": "string"
}
}
},
"RefreshResponse": {
"type": "object",
"required": ["auth_token", "csrf_token"],
"properties": {
"auth_token": {
"type": "string"
},
"csrf_token": {
"type": "string"
}
}
},
"RegisterUserRequest": {
"type": "object",
"required": ["email", "password", "password_repeat"],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"password_repeat": {
"type": "string"
}
}
},
"ResetPasswordRequest": {
"type": "object",
"required": ["email"],
"properties": {
"email": {
"type": "string"
}
}
},
"ResetPasswordUpdateRequest": {
"type": "object",
"required": ["password", "password_repeat", "password_reset_code"],
"properties": {
"password": {
"type": "string"
},
"password_repeat": {
"type": "string"
},
"password_reset_code": {
"type": "string"
},
"redirect_uri": {
"type": ["string", "null"]
}
}
},
"TokenResponse": {
"type": "object",
"required": ["auth_token", "refresh_token", "csrf_token"],
"properties": {
"auth_token": {
"type": "string"
},
"csrf_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
}
}
}
}
},
"tags": [
{
"name": "auth",
"description": "Auth-related APIs"
}
]
}