Pular para o conteúdo principal

Studio API

Auto-generated from the OpenAPI spec. Run node docs-site/scripts/fetch-openapi.js to regenerate.

GET /api/v1/studio/branding​

Get Studio Branding

Responses

  • 200 — Successful Response

GET /api/v1/studio/error-reporting​

Get Error Reporting

The studio's error-monitoring consent, plus whether toggling it would have any effect on this install (available). Manager-only.

Responses

  • 200 — Successful Response

PUT /api/v1/studio/error-reporting​

Update Error Reporting

Opt in to / out of error monitoring for this install. Takes effect immediately (no restart): enabling initialises the SDK, disabling closes it. Manager-only.

Request body

FieldRequiredTypeDescription
enabledYesboolean

Responses

  • 200 — Successful Response
  • 422 — Validation Error

GET /api/v1/studio​

Get Studio Settings

Responses

  • 200 — Successful Response

PUT /api/v1/studio​

Update Studio Settings

Request body

FieldRequiredTypeDescription
studio_nameNostring
addressNostring
countryNostring
tax_idNostring
default_vat_rateNonumber
timezoneNostring
cancellation_hoursNointeger
cancellation_deducts_creditNoboolean
late_cancel_feeNonumber
no_show_feeNonumber
checkin_open_minutes_beforeNointeger
checkin_close_minutes_afterNointeger
waitlist_confirm_minutesNointeger
guest_bookings_enabledNoboolean
self_service_purchases_enabledNoboolean
reminder_hours_beforeNointeger
calendar_start_hourNointeger
calendar_end_hourNointeger
primary_colorNostring
secondary_colorNostring
tunnel_urlNostring

Responses

  • 200 — Successful Response
  • 422 — Validation Error

GET /api/v1/studio/status​

Get Studio Status

Responses

  • 200 — Successful Response

POST /api/v1/studio/backup​

Trigger Backup

Take an on-demand SQLite snapshot of the studio database into app_data_dir()/backups/ — the same artifact the nightly backup job produces (app/tasks/nightly_backup.py).

Called by the desktop auto-updater before it applies an update, and available as a manual "back up now" action in the Settings UI. Manager-only. Prunes the backups directory to the newest 30 files and records StudioSettings.last_backup_at.

Responses

  • 200 — Successful Response

POST /api/v1/studio/reset​

Reset Studio

Wipe all studio data and return to the setup wizard (PRODUCT_SPEC.md §3.4 "Danger Zone", TECHNICAL_SPEC.md §6.2).

Full-access manager only — gated by require_manager (checks user.role.is_full_access, the same underlying flag is_full_access_staff reads for the other "superpower" gates in this codebase, e.g. retroactive bookings in bookings.py/appointments.py) — never any other staff role. require_manager is used directly rather than is_full_access_staff here because this endpoint is manager-only from the door (unlike those mixed staff/client endpoints, which authenticate broadly and only use is_full_access_staff as an in-body conditional); every other manager-only endpoint in this router (PUT /studio, POST /studio/backup, POST /studio/ai) uses the same require_manager dependency.

Re-authentication friction, both required:

  • current_password must match the caller's own password_hash (not any other manager's, if this codebase ever supports more than one full-access account) — 401 AUTH_INVALID_CREDENTIALS on mismatch, with burn_password_check() on the no-match path for timing consistency with login (SECURITY_GUIDELINES.md §1.3).
  • confirm_studio_name must exactly match StudioSettings.studio_name — 400 STUDIO_NAME_MISMATCH otherwise (including when no StudioSettings row exists at all, which can't be confirmed against anything).

On success: takes an on-demand backup (app/backup.py's perform_backup — the same function/artifact the nightly job and POST /studio/backup use) BEFORE wiping anything. If the backup itself fails, the reset is aborted with 500 BACKUP_FAILED and nothing is wiped — a mistaken reset must stay recoverable, so this never silently wipes without a fresh backup to fall back on. The wipe itself (app/services/ studio_reset_service.wipe_studio_data) deletes every table's rows in FK-safe order (never DROP, never touches alembic_version) including studio_settings itself, so needs_setup (see GET /studio/branding) evaluates true again on the next load — exactly the fresh-install state.

db.commit() happens here, once, covering both the backup's own last_backup_at write and the wipe — perform_backup commits internally (see its docstring) and wipe_studio_data never does (per backend/CLAUDE.md's transaction-semantics rule for app/services/).

Request body

FieldRequiredTypeDescription
current_passwordYesstring
confirm_studio_nameYesstring

Responses

  • 200 — Successful Response
  • 422 — Validation Error

AI Assistant configuration​

observação

The AI Assistant runs only on the studio's own AI provider key (a key saved with POST /studio/ai below, or an LLM_API_KEY in the backend's environment) or on a local keyless model (Ollama, via an ollama/ or ollama_chat/ LLM_MODEL). There is no hosted fallback: no prompt or studio data passes through infrastructure run by Agon's developer. With none of these configured, POST /agent/act and POST /support/chat answer in basic mode (mode: "basic"): a keyword documentation search with no LLM and no network call.

All /studio/ai* endpoints are manager-only (require_manager). There is no license check. User guide: How to set up the AI Assistant.


GET /api/v1/studio/ai/providers​

Get Ai Providers

List the providers a manager can bring their own key for. Never includes litellm_model — that's an internal implementation detail (see app/services/ai_providers.py's module docstring).

Responses

  • 200 — Successful Response

GET /api/v1/studio/ai​

Get Ai Status

AI status for the desktop Settings page and the assistant's basic/AI mode.

configured / provider — unchanged: whether a BYO key is stored, and for which provider. ai_configured / ai_provider / ai_source — the effective state from resolve_ai_config (BYO key, env LLM_API_KEY or local Ollama): when ai_configured is false, the assistant runs in basic mode. Never returns a key.

Responses

  • 200 — Successful Response

POST /api/v1/studio/ai​

Configure Ai

Manager only. Saves the studio's own AI provider key, which switches the assistant from basic mode to AI mode (see the configuration note above). Validates the submitted key with a live test call to the chosen provider before persisting anything; the key is then stored encrypted at rest (Fernet, app/services/crypto.py) and is never returned by any response.

Request body

FieldRequiredTypeDescription
providerYesstringOne of the id values from GET /studio/ai/providers (e.g. "gemini", "groq").
api_keyYesstringThe provider's API key. Write-only — never echoed back.

Responses

  • 200 — {"success": true}
  • 400 AI_KEY_INVALID — The provider rejected the key on the live validation call.
  • 403 — Caller is not a manager.
  • 422 AI_INVALID_PROVIDER — provider is not one of the registered provider ids. Checked before any live call is made.
  • 422 — Validation Error (missing provider or api_key).

The custom error codes above aren't captured by fetch-openapi.js's regeneration (FastAPI's OpenAPI spec doesn't include raise_api_error responses) — added by hand from app/routers/studio.py's configure_ai/get_ai_status/get_ai_providers and app/services/ai_providers.py's provider registry. Keep them if this page is regenerated.


DELETE /api/v1/studio/ai​

Remove Ai Key

Remove the studio's stored BYO AI-provider key, so the studio stops sending data to that provider — immediately, without a restart.

Clears both columns POST /studio/ai writes (gemini_api_key_encrypted, ai_provider) and the in-memory runtime key, but only when that runtime key came from the DB (see clear_runtime_byo_key): a key from the environment (.env) or a local Ollama model is operator configuration, not the studio's stored key, and stays active. Idempotent — 200 with no key stored. Returns the same shape as GET /studio/ai, so ai_configured reflects what (if anything) is still active. Never returns or logs the key.

Responses

  • 200 — Successful Response

POST /api/v1/studio/feedback​

Submit Feedback

Responses

  • 201 — Successful Response
  • 422 — Validation Error