Skip to content

Instantly share code, notes, and snippets.

@esafwan
Last active March 29, 2026 21:59
Show Gist options
  • Select an option

  • Save esafwan/076cf6a74da543f5589e9c509ba5c154 to your computer and use it in GitHub Desktop.

Select an option

Save esafwan/076cf6a74da543f5589e9c509ba5c154 to your computer and use it in GitHub Desktop.
Frappe Cloud (Press) API

Press / Frappe Cloud API Inventory (Source-Backed)

Scope and method

  • Source analyzed from backend (press/api/*, core doctypes such as Site, Site Backup, Site Group Deploy) and frontend (dashboard/src/**) to confirm exposure + payload usage.
  • This file is broad inventory. Prioritized implementation guidance is in PRESS_SAAS_API_GUIDE.md.

1) Generic API utilities / wrappers

press.api.client.* (high leverage, high risk if misused)

  • press.api.client.get_list (doctype allowlist + field/filter validation + team scoping)
  • press.api.client.get
  • press.api.client.insert
  • press.api.client.set_value
  • press.api.client.delete
  • press.api.client.run_doc_method
  • press.api.client.search_link

Key inventory notes:

  • Doctype access restricted by ALLOWED_DOCTYPES in press/api/client.py.
  • run_doc_method is restricted to methods registered through dashboard_whitelist (checked via check_dashboard_actions).
  • Team isolation enforced by check_document_access except system/support cases.

2) Site provisioning & lookup

Direct site APIs (press.api.site)

  • new
  • exists
  • options_for_new
  • get_new_site_options
  • get_domain
  • all
  • get
  • site_tags
  • installed_apps
  • available_apps
  • app_details_for_new_public_site

Related provisioning models

  • Site Group Deploy state machine (new private-bench style creation)
  • Release Group, Bench, Server, Site Plan, Frappe Version, App Source

3) Site lifecycle actions

Direct wrappers in press.api.site

  • deactivate, activate, login
  • update (schedule update)
  • migrate
  • reinstall
  • archive
  • clear_cache

Dashboard doc-method pattern (same operations via run_doc_method on Site)

  • deactivate, activate, migrate, reinstall, archive, clear_site_cache
  • plus additional Site doc methods exposed only through doc-method flow (e.g. schedule_update, edit_scheduled_update, cancel_scheduled_update, get_current_usage, refresh_database_usage)

4) Backups, restore, recovery

Direct wrappers in press.api.site

  • backups
  • backup
  • restore
  • get_backup_link
  • validate_restoration_space_requirements
  • get_upload_link, multipart_exit, uploaded_backup_info, get_backup_links

Site doc methods (dashboard-whitelisted)

  • schedule_backup
  • restore_site
  • restore_site_from_files
  • restore_site_from_physical_backup
  • get_backup_download_link

Related APIs/models

  • press.api.site_backup.create_snapshot (agent callback for physical backup snapshot creation)
  • Doctype Site Backup + status and availability model
  • Doctype Physical Backup Restoration (created by restore-from-physical flow)
  • Doctype Remote File for uploaded/imported backup artifacts

5) Migration / version-upgrade / move flows

press.api.site

  • version_upgrade
  • check_existing_upgrade_bench
  • check_app_compatibility_for_upgrade
  • create_private_bench_for_site_upgrade
  • add_server_to_release_group
  • validate_group_for_upgrade
  • get_private_groups_for_upgrade
  • change_server_options, is_server_added_in_group, change_server

Site doc methods used from dashboard

  • get_migration_options
  • create_migration_plan
  • migrate

6) App management

Site-scoped app operations

  • press.api.site.install_app
  • press.api.site.uninstall_app
  • press.api.site.available_apps
  • press.api.site.installed_apps

Marketplace APIs that influence app install/plan behavior

  • press.api.marketplace.get_install_app_options
  • press.api.marketplace.create_site_for_app
  • press.api.marketplace.get_app_plans
  • press.api.marketplace.change_app_plan
  • press.api.marketplace.get_marketplace_subscriptions_for_site

Site doc methods

  • install_app, uninstall_app (both dashboard_whitelist + site action guarded)

7) Site config / domains / environment

press.api.site

  • site_config
  • update_config
  • get_site_config_standard_keys
  • Domain operations: check_dns, domain_exists, add_domain, retry_add_domain, remove_domain, set_host_name, set_redirect, unset_redirect, domains

Site doc methods

  • update_config, delete_config
  • set_host_name, set_redirect, unset_redirect
  • add_domain, remove_domain

8) Deployments / jobs / status tracking

APIs

  • press.api.site.jobs, job, running_jobs, get_job_status
  • press.api.client.get for Site Group Deploy, Agent Job, Site, etc.

Tracking models / real-time

  • Agent Job, Agent Job Step
  • Site Activity
  • Site Group Deploy status state machine
  • Dashboard websocket subscription (doc_subscribe + doc_update) for Site Group Deploy

9) Plans / billing / subscriptions / payments

Site plan APIs

  • press.api.site.get_site_plans
  • press.api.site.get_plans
  • press.api.site.current_plan
  • press.api.site.change_plan (+ doc method set_plan path)

Billing APIs (press.api.billing) used for operational automation/sync

  • Invoices and outstanding: upcoming_invoice, get_unpaid_invoices, total_unpaid_amount, get_invoice_usage, get_summary, billing_forecast
  • Payment methods/intents: get_publishable_key_and_setup_intent, setup_intent_success, get_payment_methods, set_as_default, remove_payment_method, create_payment_intent_*, create_razorpay_order, mandate APIs

Subscription/app-plan APIs

  • Marketplace subscription/plan APIs (get_marketplace_subscriptions_for_site, change_app_plan, get_app_plans)

10) Team / ownership / transfer / access

Site transfer

  • press.api.site.send_change_team_request
  • press.api.site.confirm_site_transfer

Team/account APIs relevant to platform operator model

  • press.api.account.current_team, can_switch_to_team, switch_team, leave_team, remove_team_member, create_child_team, get_site_count
  • billing profile: get_billing_information, update_billing_information

11) Lower-priority but discovered

  • press.api.saas.* (product-trial style flows: account request, status polling, headless setup)
  • press.api.developer.saas.*, press.api.developer.marketplace.*
  • press.api.selfhosted.* (different product surface)
  • Deep database/devtools Site doc methods (run_sql_query_in_database, binlog search, index suggestions, process kill, etc.)

Status hinting across inventory

  • Active: directly used by dashboard in current source and tied to current UX.
  • Likely active: whitelisted + coherent code path but not clearly used in current dashboard.
  • Legacy/Deprecated: superseded, or only historical/unclear usage.
  • Unclear: callable in code but insufficient evidence on expected external usage pattern.

Press API Research Log

2026-03-29 Initial setup

  • Started repository-wide API surface mapping.
  • Next: enumerate API exposure points and whitelisted methods.

2026-03-29 Discovery pass 1

  • Enumerated whitelist exposure points with rg -n "@frappe.whitelist" press/api press/press -g '*.py' (902 hits overall) and then narrowed to press/api/*.py and press/api/site.py for SaaS lifecycle APIs.
  • Parsed press/api/site.py whitelisted functions and captured lifecycle wrappers (new/create, backup/restore, app install/remove, config, domain, plan, migrate/upgrade, transfer).
  • Inspected press/api/client.py to confirm generic wrapper constraints:
    • Allowed-doctype allowlist (ALLOWED_DOCTYPES).
    • Team/document access checks (check_document_access).
    • Action whitelisting for run_doc_method (check_dashboard_actions + dashboard_whitelist registry).
  • Inspected press/press/doctype/site/site.py for dashboard-callable doc methods and side effects (status transitions, agent jobs, plan changes, backup/restore semantics, config restrictions, domain validation).
  • Inspected press/press/doctype/site_backup/site_backup.py and press/api/site_backup.py for backup storage model, status filtering, physical snapshot flow and agent callback endpoint.
  • Inspected press/press/doctype/site_group_deploy/site_group_deploy.py for private-bench provisioning state machine and status transitions used by New Site progress UI.
  • Frontend-first scan:
    • rg -n "press.api" dashboard/src ... to identify endpoint usage patterns.
    • Examined New Site + New Site Progress pages for payload and websocket/polling behavior.
    • Examined dashboard/src/objects/site.js for operational actions (whitelistedMethods) and restore payload examples.
    • Extracted dt: 'Site' + method: combinations from frontend to validate real run_doc_method usage.

Open items after pass 1

  • Need deeper pass on billing + marketplace APIs that directly affect app plans/subscriptions for site automation.
  • Need explicit mapping of migration/version-upgrade flows (version_upgrade, private bench upgrade helpers).
  • Need to classify active vs likely-active vs unclear for some legacy wrappers.

2026-03-29 Discovery pass 2 (refinement)

  • Inspected upgrade/version helper APIs in press/api/site.py (version_upgrade, check_existing_upgrade_bench, compatibility checks, private-bench upgrade creation).
  • Inspected marketplace app plan/subscription endpoints in press/api/marketplace.py for app billing and plan mutation.
  • Inspected billing summary/payment endpoints in press/api/billing.py to map invoices/payment methods/forecast surface.
  • Inspected account/team ownership endpoints in press/api/account.py for team switch + transfer-adjacent flows.
  • Inspected product-trial SaaS endpoints in press/api/saas.py and classified as medium relevance / alternate onboarding path.
  • Performed frontend correlation for site actions and restore payloads from dashboard/src/objects/site.js and site components.

2026-03-29 Deliverable drafting

  • Produced:
    • PRESS_API_INVENTORY.md
    • PRESS_SAAS_API_GUIDE.md
    • PRESS_API_GAPS_AND_UNKNOWNS.md
    • PRESS_API_MACHINE_READABLE.json
  • Added explicit distinction between direct endpoints vs run_doc_method invocations.
  • Added status tagging (active / likely_active / unclear) and confidence levels.

Remaining uncertainty

  • Need runtime validation for some mixed direct-vs-doc-method behaviors and destructive defaults.
  • Need live test matrix for backup/restore/physical restore and version-upgrade payload edge cases.

PRESS_API_GAPS_AND_UNKNOWNS

Items that are ambiguous, potentially legacy, or need runtime verification on a live Frappe Cloud environment.

1) Endpoint status ambiguity (active vs legacy wrappers)

  • Many lifecycle operations are exposed both ways:
    • direct endpoint in press.api.site.*
    • press.api.client.run_doc_method to Site methods.
  • Need live validation of which style FC considers stable for long-term external integration.
  • Current dashboard heavily uses run_doc_method for many actions, but direct wrappers still exist.

2) Site creation response shape variability

  • press.api.site.new can return different tracking handles depending on path:
    • site_group_deploy
    • or site + job
  • Need runtime matrix across:
    • shared/public bench
    • private bench support plan
    • dedicated server path

3) Physical restore readiness check in frontend appears suspicious

  • In dashboard/src/objects/site.js, logic appears to flag “not ready” when row.physical && row.ready_to_restore.
  • This may be inverted (code suggests ready_to_restore=true means restorable).
  • Needs runtime/UI verification before codifying behavior.

4) Destructive action behavior variance

  • archive flow includes optional backup behavior in doc method signature (create_offsite_backup=True) but wrapper usage varies.
  • Need live verification of defaults and timing for:
    • backup creation before archive
    • immediate visibility changes in list APIs

5) Restore variants and partial-restore guarantees

  • Code supports partial file set (database / public / private / optional config), but exact restore semantics per version/agent implementation require runtime tests.
  • Need matrix:
    • DB-only restore
    • files-only restore
    • mixed restore with skip_failing_patches

6) Billing API stability for third-party automation

  • Billing APIs are broad and include regional payment paths (Stripe/Razorpay/Mpesa).
  • Need environment-specific verification:
    • which payment endpoints enabled by region/team settings
    • permission behavior for token/API key auth vs browser session

7) Plan restrictions and hidden policy checks

  • Plan changes depend on multiple runtime checks (payment_mode, recent payment state, partner billing, dedicated server flags).
  • Need integration tests to avoid false assumptions when automating plan change.

8) Team transfer confirmation path

  • confirm_site_transfer returns web redirect/HTML responses, not pure JSON API style.
  • Needs product decision:
    • use this flow as-is
    • or internalize transfer entirely with operator-owned team architecture.

9) Upgrade flow complexity / data contracts

  • version_upgrade and private-bench upgrade helpers rely on app compatibility checks and source remapping.
  • Need live test for payload details of:
    • custom_app_sources
    • scheduled time format
    • error response contracts when compatibility fails.

10) Access surface around press.api.client.*

  • ALLOWED_DOCTYPES is broad.
  • Need security review to determine if your integration should:
    • avoid generic client APIs in production abstraction,
    • or use only a strict subset.

11) SaaS/product-trial APIs (press.api.saas.*)

  • Useful for headless product signup flows, but they have assumptions tied to Account Request and trial setup pages.
  • If building fully custom onboarding, runtime verification needed before adopting these endpoints.

12) Job tracking granularity

  • Different operations expose progress via different objects:
    • Site Group Deploy
    • Agent Job / Agent Job Step
    • operation-specific doctypes (e.g., Version Upgrade, Physical Backup Restoration)
  • Need a canonical polling strategy validated across all targeted actions.
[
{
"category": "Site Provisioning",
"title": "Create Site",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.new",
"invocation_pattern": "press.api.site.new(site={...})",
"doctype": "Site",
"doc_method": "",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/pages/NewSite.vue"],
"purpose": "Provision site via shared/private/dedicated flows.",
"required_args": ["site.name", "site.plan", "site.apps"],
"optional_args": ["site.version", "site.cluster", "site.provider", "site.server", "site.selected_app_plans"],
"acts_on": ["Site", "Site Group Deploy", "Release Group", "Bench"],
"async": true,
"tracking_entities": ["Site Group Deploy", "Agent Job", "Site"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Response shape varies by provisioning path."
},
{
"category": "Site Provisioning",
"title": "Check subdomain availability",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.exists",
"invocation_pattern": "press.api.site.exists(subdomain, domain)",
"doctype": "",
"doc_method": "",
"source_files": ["press/api/site.py"],
"frontend_files": ["dashboard/src/pages/NewSite.vue"],
"purpose": "Validate name availability.",
"required_args": ["subdomain", "domain"],
"optional_args": [],
"acts_on": ["Site"],
"async": false,
"tracking_entities": [],
"danger_level": "Safe",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "allow_guest + rate-limited."
},
{
"category": "Generic API Utilities / Wrappers",
"title": "Get document",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.client.get",
"invocation_pattern": "press.api.client.get(doctype, name)",
"doctype": "*",
"doc_method": "",
"source_files": ["press/api/client.py"],
"frontend_files": ["dashboard/src/pages/NewSiteProgress.vue"],
"purpose": "Fetch doc snapshots with team access checks.",
"required_args": ["doctype", "name"],
"optional_args": [],
"acts_on": ["ALLOWED_DOCTYPES"],
"async": false,
"tracking_entities": [],
"danger_level": "Safe",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Doctype must be in allowlist."
},
{
"category": "Generic API Utilities / Wrappers",
"title": "Run document method",
"exposure_type": "run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.client.run_doc_method",
"invocation_pattern": "press.api.client.run_doc_method(dt, dn, method, args)",
"doctype": "varies",
"doc_method": "varies",
"source_files": ["press/api/client.py"],
"frontend_files": ["dashboard/src/main.js", "dashboard/src/objects/site.js"],
"purpose": "Invoke dashboard-whitelisted document operations.",
"required_args": ["dt", "dn", "method"],
"optional_args": ["args"],
"acts_on": ["Any allowed doctype with dashboard-whitelisted methods"],
"async": true,
"tracking_entities": ["Agent Job", "Site", "Site Activity"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Must pass dashboard action checks; should be wrapped internally."
},
{
"category": "Backups",
"title": "List site backups",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.backups",
"invocation_pattern": "press.api.site.backups(name)",
"doctype": "Site Backup",
"doc_method": "",
"source_files": ["press/api/site.py", "press/press/doctype/site_backup/site_backup.py"],
"frontend_files": ["dashboard/src/objects/site.js"],
"purpose": "Return logical/offsite backups with availability filtering.",
"required_args": ["name"],
"optional_args": [],
"acts_on": ["Site Backup"],
"async": false,
"tracking_entities": [],
"danger_level": "Safe",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Offsite backup count is capped by Press Settings."
},
{
"category": "Backups",
"title": "Schedule backup (doc method)",
"exposure_type": "run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.client.run_doc_method",
"invocation_pattern": "dt=Site, method=schedule_backup, args={with_files, physical}",
"doctype": "Site",
"doc_method": "schedule_backup",
"source_files": ["press/press/doctype/site/site.py", "press/press/doctype/site_backup/site_backup.py"],
"frontend_files": ["dashboard/src/components/site/SiteScheduleBackup.vue"],
"purpose": "Create backup with optional files/physical mode.",
"required_args": [],
"optional_args": ["with_files", "physical"],
"acts_on": ["Site", "Site Backup"],
"async": true,
"tracking_entities": ["Site Backup", "Agent Job"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Physical backup gated by site/system flags."
},
{
"category": "Restore / Recovery",
"title": "Restore site from files",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.restore",
"invocation_pattern": "press.api.site.restore(name, files, skip_failing_patches)",
"doctype": "Site",
"doc_method": "restore_site",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/SiteDatabaseRestoreDialog.vue", "dashboard/src/objects/site.js"],
"purpose": "Restore DB/files/config from provided remote files.",
"required_args": ["name", "files"],
"optional_args": ["skip_failing_patches"],
"acts_on": ["Site", "Remote File"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "At least one of database/public/private file is mandatory."
},
{
"category": "Restore / Recovery",
"title": "Restore from physical backup snapshot",
"exposure_type": "run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.client.run_doc_method",
"invocation_pattern": "dt=Site, method=restore_site_from_physical_backup, args={backup}",
"doctype": "Site",
"doc_method": "restore_site_from_physical_backup",
"source_files": ["press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/objects/site.js"],
"purpose": "Restore database using physical snapshot restoration workflow.",
"required_args": ["backup"],
"optional_args": [],
"acts_on": ["Site", "Physical Backup Restoration", "Site Backup"],
"async": true,
"tracking_entities": ["Physical Backup Restoration", "Agent Job", "Site"],
"danger_level": "Dangerous",
"saas_relevance": "Medium",
"confidence": "Medium",
"status": "likely_active",
"notes": "Requires physical backup feature enabled."
},
{
"category": "Restore / Recovery",
"title": "Validate restoration disk requirements",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.validate_restoration_space_requirements",
"invocation_pattern": "press.api.site.validate_restoration_space_requirements(...)",
"doctype": "Site",
"doc_method": "",
"source_files": ["press/api/site.py"],
"frontend_files": ["dashboard/src/components/BackupFilesUploader.vue"],
"purpose": "Check if app/db servers have enough free space for restore.",
"required_args": ["name", "db_file_size", "public_file_size", "private_file_size"],
"optional_args": [],
"acts_on": ["Site", "Server", "Database Server"],
"async": false,
"tracking_entities": [],
"danger_level": "Safe",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Public servers treated as expandable."
},
{
"category": "Site Actions / Lifecycle",
"title": "Reinstall site",
"exposure_type": "direct endpoint / run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.reinstall",
"invocation_pattern": "press.api.site.reinstall(name) OR dt=Site method=reinstall",
"doctype": "Site",
"doc_method": "reinstall",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/objects/site.js"],
"purpose": "Reset/reinstall site via agent job.",
"required_args": ["name"],
"optional_args": [],
"acts_on": ["Site"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Sets site status to Pending."
},
{
"category": "Site Actions / Lifecycle",
"title": "Archive site",
"exposure_type": "direct endpoint / run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.archive",
"invocation_pattern": "press.api.site.archive(name, force) OR dt=Site method=archive",
"doctype": "Site",
"doc_method": "archive",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/ArchiveSiteDialog.vue"],
"purpose": "Archive/drop site and disable related subscriptions.",
"required_args": ["name"],
"optional_args": ["force", "create_offsite_backup"],
"acts_on": ["Site", "Subscription"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Also removes upstream/proxy mapping."
},
{
"category": "App Management",
"title": "Install app on site",
"exposure_type": "direct endpoint / run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.install_app",
"invocation_pattern": "press.api.site.install_app(name, app, plan) OR dt=Site method=install_app",
"doctype": "Site",
"doc_method": "install_app",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/InstallAppDialog.vue"],
"purpose": "Install application and optionally attach marketplace plan.",
"required_args": ["name", "app"],
"optional_args": ["plan"],
"acts_on": ["Site", "Subscription", "Marketplace App"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Paid app install blocked for teams without paid capability."
},
{
"category": "App Management",
"title": "Uninstall app from site",
"exposure_type": "direct endpoint / run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.uninstall_app",
"invocation_pattern": "press.api.site.uninstall_app(name, app) OR dt=Site method=uninstall_app",
"doctype": "Site",
"doc_method": "uninstall_app",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/UninstallAppDialog.vue"],
"purpose": "Remove app and update marketplace subscription state.",
"required_args": ["name", "app"],
"optional_args": ["create_offsite_backup", "feedback"],
"acts_on": ["Site", "Subscription"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Sets site pending while job runs."
},
{
"category": "Site Config / Environment / Domains",
"title": "Read/Update site config",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.update_config",
"invocation_pattern": "press.api.site.site_config(name), press.api.site.update_config(name, config)",
"doctype": "Site",
"doc_method": "update_config",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/ConfigEditorDialog.vue"],
"purpose": "Manage customer-visible subset of site config.",
"required_args": ["name"],
"optional_args": ["config"],
"acts_on": ["Site", "Site Config"],
"async": true,
"tracking_entities": ["Agent Job"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Blacklisted/internal keys blocked; developer_mode disallowed in doc path."
},
{
"category": "Site Config / Environment / Domains",
"title": "Domain verify/add/remove/redirect",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.check_dns",
"invocation_pattern": "check_dns, add_domain, retry_add_domain, remove_domain, set_host_name, set_redirect, unset_redirect",
"doctype": "Site",
"doc_method": "add_domain/remove_domain/set_host_name/set_redirect/unset_redirect",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/AddDomainDialog.vue"],
"purpose": "Manage custom domain lifecycle and primary/redirect behavior.",
"required_args": ["name", "domain"],
"optional_args": [],
"acts_on": ["Site Domain", "Site"],
"async": true,
"tracking_entities": ["Site Domain", "Site Activity"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Includes DNS validation and reserved-domain checks."
},
{
"category": "Migration / Upgrade / Update",
"title": "Version upgrade orchestration",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.version_upgrade",
"invocation_pattern": "version_upgrade + compatibility and bench checks",
"doctype": "Site",
"doc_method": "",
"source_files": ["press/api/site.py"],
"frontend_files": ["dashboard/src/components/site/SiteVersionUpgradeDialog.vue"],
"purpose": "Schedule/start major version upgrades.",
"required_args": ["name", "destination_group"],
"optional_args": ["scheduled_datetime", "skip_failing_patches", "skip_backups"],
"acts_on": ["Version Upgrade", "Site", "Release Group"],
"async": true,
"tracking_entities": ["Version Upgrade", "Agent Job"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Destination group may be auto-resolved for shared/central benches."
},
{
"category": "Migration / Upgrade / Update",
"title": "Migration via doc method",
"exposure_type": "run_doc_method",
"http_method": "POST",
"endpoint": "/api/method/press.api.client.run_doc_method",
"invocation_pattern": "dt=Site method=create_migration_plan|get_migration_options|migrate",
"doctype": "Site",
"doc_method": "create_migration_plan / get_migration_options / migrate",
"source_files": ["press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/SiteMigration.vue"],
"purpose": "Plan and execute migration flows.",
"required_args": [],
"optional_args": ["scheduled_time", "skip_failing_patches", "skip_backups"],
"acts_on": ["Site Migration", "Site", "Agent Job"],
"async": true,
"tracking_entities": ["Agent Job", "Site"],
"danger_level": "Dangerous",
"saas_relevance": "High",
"confidence": "Medium",
"status": "likely_active",
"notes": "Used in dashboard migration UI."
},
{
"category": "Deployments / Jobs / Status Tracking",
"title": "Site job list/detail",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.jobs",
"invocation_pattern": "jobs, job, running_jobs, get_job_status",
"doctype": "Agent Job",
"doc_method": "",
"source_files": ["press/api/site.py"],
"frontend_files": ["dashboard/src/utils/agentJob.js", "dashboard/src/components/site/SiteJobs.vue"],
"purpose": "Track async job status and step output.",
"required_args": ["filters (jobs)", "job (job detail)", "name (running_jobs)"],
"optional_args": ["pagination/order"],
"acts_on": ["Agent Job", "Agent Job Step"],
"async": false,
"tracking_entities": ["Agent Job", "Agent Job Step"],
"danger_level": "Safe",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Undelivered is normalized to Pending in API response."
},
{
"category": "Plans / Billing / Subscription / Marketplace",
"title": "Site plan catalog and current plan",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.site.get_site_plans",
"invocation_pattern": "get_site_plans, get_plans, current_plan, change_plan",
"doctype": "Site Plan",
"doc_method": "set_plan",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/data/plans.js", "dashboard/src/components/site/SitePlanChangeDialog.vue"],
"purpose": "Read available plans and change plan for site.",
"required_args": [],
"optional_args": ["name", "rg", "plan"],
"acts_on": ["Site", "Site Plan", "Site Plan Change"],
"async": true,
"tracking_entities": ["Agent Job"],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Plan changes enforce payment/eligibility checks."
},
{
"category": "Plans / Billing / Subscription / Marketplace",
"title": "Marketplace app plan & subscription operations",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.marketplace.change_app_plan",
"invocation_pattern": "get_app_plans, get_marketplace_subscriptions_for_site, change_app_plan",
"doctype": "Subscription",
"doc_method": "",
"source_files": ["press/api/marketplace.py"],
"frontend_files": ["dashboard/src/components/site/SiteAppPlanSelectDialog.vue"],
"purpose": "Manage per-app subscription plans for installed marketplace apps.",
"required_args": ["subscription", "new_plan (for change)"],
"optional_args": ["site", "app"],
"acts_on": ["Subscription", "Marketplace App Plan"],
"async": false,
"tracking_entities": [],
"danger_level": "Moderate",
"saas_relevance": "High",
"confidence": "High",
"status": "active",
"notes": "Paid-plan eligibility checked against team credit/payment capability."
},
{
"category": "Plans / Billing / Subscription / Marketplace",
"title": "Billing summary/invoice APIs",
"exposure_type": "direct endpoint",
"http_method": "POST",
"endpoint": "/api/method/press.api.billing.get_summary",
"invocation_pattern": "upcoming_invoice, get_unpaid_invoices, total_unpaid_amount, get_invoice_usage, get_summary, billing_forecast",
"doctype": "Invoice",
"doc_method": "",
"source_files": ["press/api/billing.py"],
"frontend_files": ["dashboard/src/pages/BillingOverview.vue", "dashboard/src/components/billing/*"],
"purpose": "Expose billing status, invoice details and forecast data.",
"required_args": ["invoice (for usage/details)", "none for some summary calls"],
"optional_args": [],
"acts_on": ["Invoice", "Balance Transaction", "Team"],
"async": false,
"tracking_entities": [],
"danger_level": "Safe",
"saas_relevance": "Medium",
"confidence": "High",
"status": "active",
"notes": "Protected by billing role guard."
},
{
"category": "Teams / Ownership / Transfer / Access",
"title": "Site transfer request and confirmation",
"exposure_type": "direct endpoint / run_doc_method",
"http_method": "POST/GET",
"endpoint": "/api/method/press.api.site.send_change_team_request",
"invocation_pattern": "send_change_team_request(name, team_mail_id, reason) + confirm_site_transfer(key)",
"doctype": "Site",
"doc_method": "send_change_team_request",
"source_files": ["press/api/site.py", "press/press/doctype/site/site.py"],
"frontend_files": ["dashboard/src/components/site/SiteTransferDialog.vue"],
"purpose": "Transfer site ownership between teams.",
"required_args": ["name", "team_mail_id", "reason"],
"optional_args": ["key (confirm)"],
"acts_on": ["Site", "Team Change"],
"async": true,
"tracking_entities": ["Team Change"],
"danger_level": "Moderate",
"saas_relevance": "Medium",
"confidence": "High",
"status": "active",
"notes": "Confirmation endpoint may respond with web redirects/pages."
}
]

PRESS_SAAS_API_GUIDE

Implementation-oriented API map for building a customer-safe SaaS control plane on top of Press/Frappe Cloud.

How to read this

  • Focus: APIs needed for provisioning + ongoing site/app lifecycle without exposing FC UI.
  • Evidence source: Press backend + dashboard frontend usage.
  • “Invocation Pattern” can be either direct endpoint or run_doc_method call.

1) Create Site (Primary provisioning entry)

  • Category: Site Provisioning
  • Exposure Type: direct endpoint
  • Endpoint or Invocation Pattern: /api/method/press.api.site.new
  • HTTP Method: POST
  • Source of Exposure: press.api.site.new
  • Primary Source Files: press/api/site.py
  • Related Frontend Files: dashboard/src/pages/NewSite.vue
  • Purpose: Creates new site via shared/public flow OR private bench/dedicated server flow.
  • When We Would Use It: Primary provisioning API for customer site creation.
  • Required Arguments:
    • site.name (subdomain)
    • site.plan
    • site.apps (typically includes frappe + chosen apps)
    • site.version, site.cluster; optionally provider/server
  • Optional Arguments:
    • localisation_country, selected_app_plans, share_details_consent, domain
  • Example Payload:
    • { "site": { "name": "acme", "apps": ["frappe","erpnext"], "version": "Version 16", "cluster": "Falkenstein", "plan": "...", "domain": "..." } }
  • Example Response Shape:
    • Shared/private-existing-bench path may return site + job; bench-provision flow returns site_group_deploy.
  • Acts On: Site, Site Group Deploy, Release Group, Bench
  • Permission / Preconditions:
    • Team creation permission checks (team.can_create_site in SGD flow)
    • plan validation and app/version constraints
  • Side Effects:
    • DNS/default domain creation, site activity log, agent jobs, possible subscription creation
  • Async Behavior: yes
  • Tracking / Polling Model:
    • Site Group Deploy status OR Agent Job + Site.status
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Recommended Abstraction in Our Product:
    • provisionSite(request) -> {tracking_type, tracking_id} with normalized tracker.
  • Notes / Caveats:
    • Behavior differs by plan/server/private bench support.
  • Confidence: High

2) Check Subdomain Availability

  • Category: Site Provisioning
  • Exposure Type: direct endpoint
  • Endpoint or Invocation Pattern: /api/method/press.api.site.exists
  • HTTP Method: POST/GET
  • Source of Exposure: press.api.site.exists (allow_guest=True, rate-limited)
  • Primary Source Files: press/api/site.py
  • Related Frontend Files: dashboard/src/pages/NewSite.vue
  • Purpose: Verifies if subdomain under root domain is available.
  • When We Would Use It: Preflight validation before submit.
  • Required Arguments: subdomain, domain
  • Optional Arguments: none
  • Example Response Shape: boolean-like response from Site.exists.
  • Acts On: Site existence
  • Permission / Preconditions: public callable
  • Side Effects: none
  • Async Behavior: no
  • Tracking / Polling Model: n/a
  • Danger Level: Safe
  • SaaS Relevance: High
  • Recommended Abstraction in Our Product: checkSiteNameAvailable(name, domain)
  • Notes / Caveats: rate limited.
  • Confidence: High

3) Track Creation / Long-Running Deploy

  • Category: Deployments / Jobs / Status Tracking
  • Exposure Type: REST resource via generic client + websocket
  • Endpoint or Invocation Pattern:
    • press.api.client.get with {doctype: "Site Group Deploy", name: <id>}
    • websocket doc_subscribe for Site Group Deploy
  • HTTP Method: POST (API), socket events
  • Source of Exposure: press.api.client.get, SiteGroupDeploy doctype state machine
  • Primary Source Files: press/api/client.py, press/press/doctype/site_group_deploy/site_group_deploy.py
  • Related Frontend Files: dashboard/src/pages/NewSiteProgress.vue
  • Purpose: Observe private-bench provisioning states.
  • Required Arguments: doctype + name
  • Example Response Shape: includes status, release_group, site
  • Tracking Entities: Site Group Deploy status values:
    • Pending, Deploying Bench, Bench Deployed, Creating Site, Site Created, Bench Deploy Failed, Site Creation Failed
  • Danger Level: Safe
  • SaaS Relevance: High
  • Recommended Abstraction: unified waitForProvisioning() with fallback polling.
  • Confidence: High

4) Generic Document Getter (Core utility)

  • Category: Generic API Utilities / Wrappers
  • Exposure Type: direct endpoint
  • Endpoint or Invocation Pattern: /api/method/press.api.client.get
  • HTTP Method: POST
  • Source of Exposure: press.api.client.get
  • Primary Source Files: press/api/client.py
  • Purpose: Fetch doc snapshots (Site, Agent Job, Site Backup, etc.) with team guards.
  • Required Arguments: doctype, name
  • Preconditions: doctype must be in ALLOWED_DOCTYPES; doc must belong to team unless support/system override.
  • Danger Level: Safe
  • SaaS Relevance: High
  • Recommended Abstraction: read-model API; use for status sync.
  • Confidence: High

5) Generic Doc Method Runner (High-power action wrapper)

  • Category: Generic API Utilities / Wrappers
  • Exposure Type: direct endpoint (run_doc_method)
  • Endpoint or Invocation Pattern: /api/method/press.api.client.run_doc_method
  • HTTP Method: POST
  • Source of Exposure: press.api.client.run_doc_method
  • Primary Source Files: press/api/client.py
  • Purpose: Invoke dashboard-whitelisted methods on docs.
  • Required Arguments: dt, dn, method, optional args
  • Preconditions:
    • method must be present in doc actions and registered via dashboard_whitelist
    • doctype permission + team document access enforced
  • Side Effects: action-specific; response injects refreshed doc in docs list.
  • Async Behavior: action-dependent (many site methods enqueue agent jobs).
  • Danger Level: Dangerous (if exposed raw)
  • SaaS Relevance: High
  • Recommended Abstraction:
    • Never expose raw method selection to customers.
    • Wrap each approved operation as typed server-side command.
  • Confidence: High

6) Schedule/Trigger Backup

  • Category: Backups
  • Exposure Type: direct endpoint + run_doc_method option
  • Endpoint or Invocation Pattern:
    • direct: /api/method/press.api.site.backup
    • doc method: run_doc_method(dt="Site", method="schedule_backup")
  • HTTP Method: POST
  • Source of Exposure: press.api.site.backup, Site.schedule_backup, Site.backup
  • Primary Source Files: press/api/site.py, press/press/doctype/site/site.py, press/press/doctype/site_backup/site_backup.py
  • Related Frontend Files: dashboard/src/components/site/SiteScheduleBackup.vue, dashboard/src/objects/site.js
  • Purpose: Create logical/physical/offsite backup records and agent jobs.
  • Required Arguments:
    • direct: name, optional with_files
    • doc method: with_files, physical
  • Side Effects:
    • Inserts Site Backup
    • May enqueue backup job / physical backup workflow
    • Applies pending-backup rate limits
  • Async Behavior: yes
  • Tracking / Polling Model:
    • Site Backup.status, linked Agent Job, Site Activity
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Recommended Abstraction: createBackup(site, mode) + job/backups watcher.
  • Confidence: High

7) List Backups

  • Category: Backups
  • Exposure Type: direct endpoint
  • Endpoint or Invocation Pattern: /api/method/press.api.site.backups
  • HTTP Method: POST
  • Source of Exposure: press.api.site.backups
  • Primary Source Files: press/api/site.py, press/press/doctype/site_backup/site_backup.py
  • Purpose: Returns latest local + offsite backups filtered for file availability.
  • Required Arguments: name
  • Return Notes:
    • Includes remote file links/ids and metadata
    • excludes unavailable files
  • Danger Level: Safe
  • SaaS Relevance: High
  • Confidence: High

8) Restore Site from Backup Files

  • Category: Restore / Recovery
  • Exposure Type: direct endpoint OR run_doc_method
  • Endpoint or Invocation Pattern:
    • direct: /api/method/press.api.site.restore
    • doc method: restore_site_from_files or restore_site
  • HTTP Method: POST
  • Source of Exposure: press.api.site.restore, Site.restore_site*
  • Primary Source Files: press/api/site.py, press/press/doctype/site/site.py
  • Related Frontend Files: dashboard/src/components/site/SiteDatabaseRestoreDialog.vue, dashboard/src/objects/site.js
  • Purpose: Restore DB/public/private/config from selected remote backup files.
  • Required Arguments:
    • name
    • files object with at least one of database|public|private (config optional)
  • Preconditions:
    • At least one file present
    • file references must exist (Remote File) if used by doc methods
  • Side Effects:
    • writes remote_*_file pointers on Site
    • schedules restore agent job, sets Site.status=Pending
  • Async Behavior: yes
  • Tracking / Polling Model: returned job id + Agent Job, Site.status
  • Danger Level: Dangerous
  • SaaS Relevance: High
  • Recommended Abstraction: explicit restore workflow with confirmation + typed file selectors.
  • Confidence: High

9) Restore from Physical Backup Snapshot

  • Category: Restore / Recovery
  • Exposure Type: run_doc_method (Site doc)
  • Endpoint or Invocation Pattern: run_doc_method(dt="Site", method="restore_site_from_physical_backup", args={backup})
  • HTTP Method: POST
  • Source of Exposure: Site.restore_site_from_physical_backup
  • Primary Source Files: press/press/doctype/site/site.py
  • Related Frontend Files: dashboard/src/objects/site.js
  • Purpose: Builds Physical Backup Restoration doc and executes restore.
  • Required Arguments: backup (Site Backup name)
  • Preconditions: physical restore must be globally enabled
  • Side Effects: Site.status set Pending; restoration workflow doc created
  • Async Behavior: yes
  • Tracking / Polling Model: restoration doc / jobs + site status
  • Danger Level: Dangerous
  • SaaS Relevance: Medium-High
  • Confidence: Medium

10) Backup File Upload / Import From URL

  • Category: Backups / Restore Inputs
  • Exposure Type: direct endpoints
  • Endpoints:
    • press.api.site.get_upload_link
    • press.api.site.multipart_exit
    • press.api.site.uploaded_backup_info
    • press.api.site.get_backup_links
  • Purpose: Upload backup artifacts to remote storage or pull backup links from external Frappe site.
  • Key Caveat:
    • get_backup_links(url,email,password) is credential-sensitive and may be unsuitable for customer exposure.
  • SaaS Relevance: High for migration onboarding flows.
  • Confidence: High

11) Validate Restore Capacity Before Upload

  • Category: Restore / Recovery
  • Exposure Type: direct endpoint
  • Endpoint: press.api.site.validate_restoration_space_requirements
  • Purpose: Compares required restore space vs free app/db server space.
  • Required Args: name, db_file_size, public_file_size, private_file_size
  • Response: booleans for insufficiency by server + required/free numbers.
  • Notes: public servers treated as expandable (allowed_to_upload=True).
  • SaaS Relevance: High
  • Confidence: High

12) Reinstall / Reset Site

  • Category: Site Actions / Lifecycle
  • Exposure Type: direct + run_doc_method
  • Endpoint(s): press.api.site.reinstall OR doc method reinstall
  • Purpose: destructive reset/reinstall, sets site Pending, runs agent job.
  • Side Effects: data reset behavior; status transition and job scheduling.
  • Tracking: returned job + Site.status polling.
  • Danger Level: Dangerous
  • SaaS Relevance: High
  • Confidence: High

13) Archive/Drop Site

  • Category: Site Actions / Lifecycle
  • Exposure Type: direct + run_doc_method
  • Endpoint(s): press.api.site.archive OR doc method archive
  • Purpose: archive/drop site, remove upstream from proxy, disable subscriptions.
  • Important Args: force (direct wrapper), create_offsite_backup (doc method signature supports)
  • Side Effects: host_name removal, subscription disable, db-user archiving.
  • Danger Level: Dangerous
  • SaaS Relevance: High
  • Confidence: High

14) App Install / Uninstall

  • Category: App Management
  • Exposure Type: direct endpoint + run_doc_method
  • Endpoint(s):
    • press.api.site.install_app(name, app, plan=None)
    • press.api.site.uninstall_app(name, app)
    • doc methods install_app / uninstall_app
  • Purpose: modify app set on running site.
  • Side Effects:
    • Agent job created
    • Site.status=Pending
    • marketplace subscription/app-plan hooks are updated
  • Preconditions:
    • paid app install checks (team.can_install_paid_apps)
  • Tracking: returned job id / site pending status
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Confidence: High

15) Site Config Update (safe subset)

  • Category: Site Config / Environment
  • Exposure Type: direct endpoint + doc method
  • Endpoint(s): press.api.site.site_config, press.api.site.update_config
  • Purpose: read/update site config with sanitization.
  • Restrictions:
    • blacklisted/internal keys excluded
    • type coercion (Number/Boolean/JSON/Password)
    • developer_mode explicitly blocked in Site doc update flow
  • Side Effects: triggers Agent.update_site_config
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Recommended Abstraction: strict allowlist in your own control plane.
  • Confidence: High

16) Custom Domains

  • Category: Site Config / Domains
  • Exposure Type: direct endpoint + doc methods
  • Endpoint(s):
    • check_dns, add_domain, retry_add_domain, remove_domain
    • set_host_name, set_redirect, unset_redirect
    • domain_exists, domains
  • Purpose: attach/manage custom domains and redirect policy.
  • Preconditions: DNS validation checks via CNAME/A match and reserved-domain checks.
  • Side Effects: Site Domain rows + proxy/domain agent actions.
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Confidence: High

17) Site Plan Retrieval + Change

  • Category: Plans / Billing / Subscription
  • Exposure Type: direct + doc method
  • Endpoints:
    • get_site_plans, get_plans, current_plan, change_plan
    • doc method set_plan
  • Purpose: inspect plan catalog + current usage context + apply plan changes.
  • Preconditions:
    • payment/card/credits checks (can_change_plan path)
    • dedicated/non-dedicated compatibility filtering
  • Side Effects: Site Plan Change, config updates, possible unsuspend/reactivation handling.
  • Danger Level: Moderate
  • SaaS Relevance: High
  • Confidence: High

18) Version Upgrade (major)

  • Category: Migration / Upgrade / Update
  • Exposure Type: direct endpoints
  • Endpoints:
    • version_upgrade
    • check_existing_upgrade_bench
    • check_app_compatibility_for_upgrade
    • create_private_bench_for_site_upgrade
    • helper: get_private_groups_for_upgrade, validate_group_for_upgrade
  • Purpose: orchestrate major version progression and destination bench strategy.
  • Async Behavior: yes (Version Upgrade docs/jobs)
  • Tracking: job/deploy docs depending on path.
  • Danger Level: Dangerous
  • SaaS Relevance: High
  • Confidence: High

19) Migrate / Update (minor/operational)

  • Category: Migration / Upgrade / Update
  • Exposure Type: direct + run_doc_method
  • Endpoints: update, migrate, last_migrate_failed, plus doc methods create_migration_plan, get_migration_options
  • Purpose: apply migrations/updates and schedule updates.
  • Side Effects: Site.status=Pending, Site Update records, agent jobs.
  • Danger Level: Moderate-Dangerous
  • SaaS Relevance: High
  • Confidence: High

20) Job and Activity Tracking

  • Category: Deployments / Jobs / Status Tracking
  • Exposure Type: direct endpoints
  • Endpoints:
    • press.api.site.jobs, job, running_jobs, get_job_status, activities
  • Purpose: present progress/details for async actions.
  • Acts On: Agent Job, Agent Job Step, Site Activity
  • SaaS Relevance: High
  • Confidence: High

21) Team Transfer / Ownership

  • Category: Teams / Ownership / Transfer / Access
  • Exposure Type: direct endpoints + doc method
  • Endpoints:
    • press.api.site.send_change_team_request
    • press.api.site.confirm_site_transfer (link-based)
    • account helpers (can_switch_to_team, switch_team, remove_team_member, etc.)
  • Purpose: ownership transfer and operator-team routing.
  • SaaS relevance:
    • High if your control plane maps customers to internal teams.
    • Medium if you run all sites under one operator team.
  • Confidence: High

22) Billing / Invoice / Payment Methods (control-plane sync layer)

  • Category: Plans / Billing / Subscription
  • Exposure Type: direct endpoints
  • Core endpoints to track:
    • press.api.billing.upcoming_invoice
    • press.api.billing.get_unpaid_invoices
    • press.api.billing.total_unpaid_amount
    • press.api.billing.get_invoice_usage
    • press.api.billing.get_summary
    • press.api.billing.billing_forecast
    • payment setup/method APIs (get_publishable_key_and_setup_intent, setup_intent_success, get_payment_methods, etc.)
  • Purpose: billing state synchronization, unpaid handling, and payment method lifecycle.
  • SaaS Relevance: Medium-High (depends if FC billing is customer-facing or internalized).
  • Confidence: High

Recommended implementation pattern for your own SaaS layer

  1. Build a strict internal command API (no raw run_doc_method exposed).
  2. Normalize tracking IDs into one abstraction (Site Group Deploy vs Agent Job).
  3. Maintain per-site “operation ledger” in your product with:
    • request payload hash
    • FC endpoint called
    • FC tracker id(s)
    • terminal status + error payload snapshot
  4. Enforce your own policy guardrails:
    • destructive action approvals (reinstall/archive/restore)
    • config key allowlist
    • app allowlist per plan/tier
  5. Use direct typed endpoints when available; use run_doc_method for missing capabilities only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment