Developer reference

A1 Tools API Guide

Every endpoint and action the platform exposes — the same catalog that powers the in-app Job Workflow builder. 1340 actions across 199 endpoints, generated directly from source on 2026-08-21.

W = writes data · R = read-only · Auth badge shows the credential each endpoint expects.

All authenticated endpoints require your organization's API token in the X-API-Token header plus a user identity — contact your account manager for credentials. Base URL: https://app.a-1chimney.com/api/

admin — 12 endpoints

accept_invite.php accept_invite.php — PUBLIC, token-gated invite redemption endpoint. one-time token
actiondescription
?action=set_password R
?action=validate R
app_settings_admin.php App Settings admin API — read/write the global tunables declared in X-API-Token company-scoped
actiondescription
?action=list R Platform authority only — these knobs are global and several are safety-relevant.
?action=reset W Platform authority only — these knobs are global and several are safety-relevant.
?action=save W Platform authority only — these knobs are global and several are safety-relevant.
audit_log.php Audit Log API X-API-Token
actiondescription
?action=actions R Get distinct actions
?action=categories R Get distinct categories
?action=export W Export logs to CSV
?action=list R List audit logs (with filters)
?action=log W Log an action (internal use)
?action=stats R Get audit statistics
branding.php X-API-Token company-scoped
actiondescription
?action=save_company R
?action=save_org R
?action=upload_logo R
org_data_export.php X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

org_upgrade.php X-API-Token
actiondescription
?action=activate R
?action=list_requests R
?action=request_upgrade R
password_reset.php Handles password reset via email one-time token
actiondescription
?action=request R
?action=reset R
?action=verify R
people.php Unified People API X-API-Token company-scopedrole-gated
actiondescription
?action=create W
?action=create_role W owner-only; label + slug + optional capability flags.
?action=deactivate W
?action=delete_document W
?action=delete_picture W
?action=delete_role W owner-only; role_key + reassign_to (required if users hold it).
?action=ensure_hr_record W
?action=get R
?action=get_document W ---- POST actions ----
?action=list R
?action=list_roles W roles for the caller's org + per-role user_count.
?action=migrate W ---- Org-scoped actions (self-gated via orgCaller / userCanEditOrgSettings) ----
?action=org_create_user W create a new user scoped to the caller's org.
?action=org_deactivate_user W set is_active=0 for an org-scoped user.
?action=org_list_users R list all users in the caller's org.
?action=org_reactivate_user W set is_active=1 for an org-scoped user.
?action=org_reorder_users W persist a drag-reordered team order (#128).
?action=org_reset_password W set a new password for an org-scoped user.
?action=org_update_user W update role, org_role, and company access for an org-scoped user.
?action=permanent_delete W
?action=reactivate W Hard delete — POST only (dispatch runs before any method check).
?action=reset_password W
?action=save_role W owner-only; label (custom roles) + capability flags by id.
?action=set_role_capability W owner-only; one (role_key, cap_key, value) toggle.
?action=transfer_ownership W atomically hand org ownership to another active user in the caller's org (current owner -> admin, target -> owner).
?action=update W
?action=upload_document W
?action=upload_picture W
?action=version R
signup.php HMAC signature
actiondescription
?action=form_token R
?action=resend R
?action=start R
?action=verify R
suggestions.php API for user suggestions for app improvements. X-API-Token company-scopedrole-gated
actiondescription
?action=attach_reply W Attach a document to a suggestion as the REVIEWER's reply.
?action=claim_review_request W The poller's endpoint.
?action=complete_review_request W
?action=delete W Delete a suggestion
?action=delete_mine W Submitter deletes their OWN suggestion (any status).
?action=images W All images for one suggestion, oldest-first (sort_order).
?action=list R List all suggestions (with optional status filter)
?action=list_mine R Personal "My Suggestions" feed.
?action=request_review W
?action=review_request_status W What the button shows.
?action=review_schedule R Next-review countdown for the Suggestions tab.
?action=submit W Submit a new suggestion
?action=update_mine W Edit the text of one's own suggestion — pending-only.
?action=update_status W Update suggestion status
suggestions_autoreview_report.php Emails the daily Autonomous Suggestion Review summary to a recipient. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

user_management.php User Management API X-API-Token company-scopedrole-gated
actiondescription
?action=create R
?action=deactivate R
?action=delete R
?action=get R
?action=get_crm_admin R
?action=list R
?action=permanent_delete R
?action=reactivate R
?action=reset_password R
?action=update R
?action=update_schedule R

clocker — 10 endpoints

clocker/audio_retention_cron.php Audio-safety retention cron — AS3b (2026-07-09). URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

clocker/audio_safety.php X-API-Token company-scopedrole-gated
actiondescription
?action=begin W create a recording row.
?action=chunk W persist one uploaded AAC chunk.
?action=event W journal one typed event onto an owned recording.
?action=finish W finalize an owned recording: ended_at = NOW(), stop_reason, duration_s = seconds since started_at (computed in MySQL so clock math stays in one place, per the GPS-rebuild hard rules).
?action=flag W management+ (same org rule).
?action=list W see the file header for the full contract. $opt keys: recording_id, target_username, all (bool), crm_job_id, limit, offset.
?action=stream W resolve the ordered chunk descriptors for a recording (management+ + org rule via audioSafetyRecordingForManagement). $seq selects one chunk; null = every chunk in seq order (the concatenated whole-re
?action=unflag W management+ (same org rule).
clocker/gps_endpoints.php Technician GPS pipeline (Phase 3 of the rebuild). X-API-Token (per action; ?action=public is anonymous) company-scopedrole-gated
actiondescription
?action=active W
?action=ingest W
?action=route W
clocker/stale_shift_alerts.php GPS Stale-Shift Alerts URL key / cron token role-gated

Single-purpose endpoint — no ?action= dispatch.

clocker/tech_clock_daily_report.php Technician End-of-Day Report — per area (franchise), to that area's manager. anonymous

Single-purpose endpoint — no ?action= dispatch.

clocker/technician_clock.php Technician Clock-In/Out API X-API-Token company-scopedrole-gated
actiondescription
?action=acknowledge_all_warnings W
?action=acknowledge_warning W
?action=approve W Approve clock-in request
?action=approve_extension W
?action=auto_clock_out_midnight W Daily timezone-aware close
?action=clock_out W Clock out (ends shift)
?action=cron_shift_sms_warnings W 5-min SMS cap warnings
?action=deny W Deny clock-in request
?action=deny_extension W
?action=geocode_address W Geocode a free-text address to coordinates (Google Maps, server-side) so the Clock-in Zones UI can "search an address" to drop a franchise center, then let the manager fine-tune it by tapping the map.
?action=get_auto_approve W api/clocker/handlers/auto_approve.php Extracted 2026-05-04 from technician_clock.php as part of #25.
?action=get_battery_history R api/clocker/handlers/battery.php Extracted 2026-05-04 from technician_clock.php as part of #25.
?action=get_battery_report R
?action=get_cap_settings R api/clocker/handlers/cap_geofence.php Extracted 2026-05-04 from technician_clock.php as part of #25.
?action=get_extension_status R
?action=get_field_reports R Device-state report — technicians' phones POST a permission/setting
?action=get_franchise_geofences R Clock-in zone config (2026-06-05): list the franchises in the manager's company with their per-franchise geofence (center + enabled + radius).
?action=get_geofence_events R
?action=get_geofence_settings R zone config
?action=get_pending W List pending requests (company/franchise scoped)
?action=get_pending_extensions R
?action=get_pending_extensions_count R
?action=get_request_status R Poll for approval status
?action=get_route_calendar R Field Map secondary panels — restored after Phase 1 wholesale delete.
?action=get_tech_records W Time records for Work Hours tab
?action=get_tech_status W Get overall tech status (pending/clocked_in/out)
?action=get_warning_count R
?action=get_warnings R
?action=grant_extension W
?action=report_device_state W api/clocker/handlers/device_state.php Receives `DeviceStateProbe` snapshots from technicians' phones.
?action=request_clock_in W Submit clock-in request (pending approval)
?action=request_extension W api/clocker/handlers/extensions.php Extracted 2026-05-04 from technician_clock.php as part of #25.
?action=set_auto_approve W
?action=set_cap_settings W Geofence settings & events
?action=set_franchise_geofence W Update one franchise's clock-in geofence (enabled / radius / center lat,lng).
?action=set_geofence_settings W
?action=set_user_auto_approve W
clocker/time_clock.php Time Clock API v2 X-API-Token company-scopedrole-gated
actiondescription
?action=add_extra_hours W Add extra hours for a user (separate from main clock in/out, won't merge)
?action=all_records W Get all users' time records (managers+)
?action=auto_clock_out_midnight W Cron job to auto clock out at midnight
?action=auto_clock_out_scheduled W Auto clock out users based on their schedule (called by cron every 15-30 minutes) This clocks out users who are past their scheduled end time
?action=clock_in W Clock in user
?action=clock_out W Clock out user
?action=correct_record W Correct a time record (edit clock in/out times) Only managers, admins, and developers can do this
?action=create_record W Create a new time record manually (for managers to add missing days)
?action=delete_record W Delete a time record (admin only)
?action=fill_missing_days R Fill missing days with "not worked" status
?action=get_day_statuses R Get day statuses for date range
?action=get_schedule R Get work schedule
?action=get_today_schedule R Get today's schedule override for a user
?action=records W Get time records
?action=set_day_status W Set day status (vacation, sick, absent, notes)
?action=set_schedule W Set work schedule
?action=set_today_schedule W Set schedule override for today (self-service for employees) Allows user to change their own schedule for the current day
?action=status R Get current clock status
?action=update_record_notes W Update notes on a specific time record
clocker/time_clock_cron.php Office Worker Auto-Absence Cron URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

timesheets.php Dispatcher timesheets read API (A1 Tools → A1 Leads wire). HMAC signature

Single-purpose endpoint — no ?action= dispatch.

weekly_time_report.php Weekly Time Report Email X-API-Token (per action; ?action=public is anonymous) company-scopedrole-gated
actiondescription
?action=debug R Weekly Time Report Email Sends a weekly summary of employee hours to management. / // Clear opcache for this file to ensure latest code runs if (function_exists('opcache_invalidate')) { opcache_invali
?action=get_report_settings W Gate for the report-settings actions.
?action=preview W Id of the synthesized definition when nothing has been configured. */ const WEEKLY_REPORT_DEFAULT_ID = 'default'; /** app_settings key holding the JSON definition array. */ const WEEKLY_REPORT_DEFINIT
?action=save_report_settings W Gate for the report-settings actions.
?action=send_report W Build and (unless previewing) send one report definition's email.

crm — 40 endpoints

crm/a1_leads.php A1 Leads — CRM-side query API. X-API-Token company-scopedrole-gated
actiondescription
?action=clear_config W Username-keyed tier gate — the drop-in replacement for the frozen APP_ADMIN_ROLES / APP_ADMIN_ROLES_MGMT membership tests at the ~117 sites that key on a username: userRoleInSet($pdo, $u, APP_ADMIN_RO
?action=count_unread W Gate for the lead-READ actions (list / get / stats / count_unread).
?action=get W Gate for the lead-READ actions (list / get / stats / count_unread).
?action=get_config W Org isolation + access gate: ANY user with CRM access to this company
?action=list W Gate for the lead-READ actions (list / get / stats / count_unread).
?action=mark_promoted W
?action=probe_config W A1 Leads — CRM-side query API.
?action=set_config W Username-keyed tier gate — the drop-in replacement for the frozen APP_ADMIN_ROLES / APP_ADMIN_ROLES_MGMT membership tests at the ~117 sites that key on a username: userRoleInSet($pdo, $u, APP_ADMIN_RO
?action=stats W Gate for the lead-READ actions (list / get / stats / count_unread).
crm/a1_leads_proxy.php A1 Leads — same-origin proxy (web only). X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

crm/a1_leads_webhook.php A1 Leads webhook receiver. HMAC signature company-scoped

Single-purpose endpoint — no ?action= dispatch.

crm/access.php CRM Access API - User Access Control X-API-Token company-scopedrole-gated
actiondescription
?action=assign_company W Assign user to a company
?action=assign_franchise W Assign user to a franchise
?action=available_users R List all users for assignment
?action=company_users W List users assigned to a company
?action=delete_org_tab_permission W Remove an org-level tab permission row
?action=delete_tab_permission W Remove company-level tab override (reverts to org default)
?action=franchise_users R List users assigned to a franchise
?action=get_messaging_permissions W The messaging role-to-role allowlist map for one scope.
?action=get_org_tab_permissions R List all org-level tab permissions for an org
?action=get_user_tab_overrides W Get tab overrides for a specific user in a company
?action=get_work_hours_visibility W The org's Work Hours role-visibility map.
?action=remove_user_tab_override W Remove a per-user tab override
?action=set_user_tab_override W Grant a user access to a specific tab (additive override)
?action=tab_permissions W Get tab permissions for a company
?action=tab_permissions_detail W Per-tab detail: org row, company row, effective, source
?action=unassign_company W Remove user from a company
?action=unassign_franchise W Remove user from a franchise
?action=update_messaging_permissions W Replace the whole messaging allowlist map for one scope.
?action=update_org_tab_permission W Upsert an org-level tab permission
?action=update_tab_permissions W Update tab permissions
?action=update_work_hours_visibility W Set or clear ONE viewer role's entry in the org's Work Hours role-visibility map.
?action=user_access W Get all access for a user
crm/address_autocomplete.php CRM Address Autocomplete API X-API-Token company-scoped
actiondescription
?action=details W Street/city/state/zip + lat/lng for one prediction
?action=suggest W Address predictions for a partial query
crm/availability.php api/crm/availability.php — the Availability tab's endpoint. X-API-Token company-scoped
actiondescription
?action=board W api/crm/availability.php — the Availability tab's endpoint.
?action=check_zip W Check if user has access to a specific franchise
?action=day_lookup W Check if user has access to a specific franchise
?action=grid R Check if user has access to a specific franchise
?action=month W Check if user has access to a specific franchise
?action=next_available W Scan forward for the days something is actually bookable (2026-08-16).
?action=set_area_standing W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_area_technician W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_area_weekday W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_capacity W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_day W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_day_cap W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_standing W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
?action=set_weekday W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
crm/cameras.php X-API-Token company-scopedrole-gated
actiondescription
?action=agent_targets W The on-site bridge asks "which cameras do I push, and how do I reach them?" Returns active, snapshot-bridgeable cameras in the caller's franchise scope, each with its resolved snapshot URL and — for d
?action=brands W profile catalog (so no client hardcodes it)
?action=delete W ── View bridge (see agent_targets/push_frame/get_frame docs) ──
?action=get_frame W Viewer fetches a camera's latest frame.
?action=list W
?action=push_frame W The agent POSTs one camera's latest JPEG as the raw request body (Content-Type image/jpeg); company_id + camera_id ride in the query.
?action=save W
crm/citation_builder.php Citation Map Builder — pure row generation. UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

crm/citations.php CRM Citation Map Builder API X-API-Token company-scopedrole-gated
actiondescription
?action=build W
?action=delete_profile W
?action=download R
?action=generate_areas W
?action=geocode_areas W
?action=get_profile R
?action=list_profiles R
?action=list_runs R
?action=preflight W
?action=save_profile W
crm/clients.php CRM Clients API X-API-Token company-scoped
actiondescription
?action=add_contact W
?action=add_payment_method W
?action=assign_franchise W Assign client to franchise
?action=create W Create new client
?action=delete W Delete client (developer=hard, admin=soft)
?action=delete_contact W
?action=delete_payment_method W
?action=get R Get single client with franchises
?action=history R Activity history for client
?action=list R Paginated client list
?action=match_names R Batch exact name -> contact lookup
?action=search R Full-text search
?action=unassign_franchise W Remove client from franchise
?action=update W Update client
?action=update_contact W
?action=update_payment_method W
crm/companies.php CRM Companies API X-API-Token company-scopedrole-gated
actiondescription
?action=bootstrap W Bootstrap payload for the app's TenantContext: the caller's organization, the platform-admin flag, the caller's org role, and the org-scoped company list.
?action=create W Create new company (developer/admin only)
?action=delete W Delete company (developer only)
?action=get W Get single company with franchise list
?action=list W List companies the user has access to
?action=list_orgs R Cross-org PLATFORM AUTHORITY (R7, 2026-07-09): the is_platform_admin flag (via userIsPlatformAdmin, which also admits lead developers) OR the 'developer' role. role='developer' transcends organization
?action=remove_logo W Remove company brand logo
?action=update W Update company (company admin+ access)
?action=upload_logo W Upload company brand logo (multipart)
crm/email.php CRM Email API — Phase 1: Account management (CRUD) X-API-Token company-scoped
actiondescription
?action=approve_autoreply W Admin approves + sends a queued draft-mode auto-reply.
?action=bimi_logos W Batch-resolve sender domains to BIMI logo URLs.
?action=create_account W
?action=delete_account W
?action=delete_autoreply_rule W Delete an auto-reply rule, scoped to company_id.
?action=delete_filter W POST delete_filter Body param: id Cascade deletes conditions + assignments via FK.
?action=delete_template W Delete a template, scoped to company_id.
?action=download_attachment R CRM Email Attachments — download endpoint.
?action=get_account R
?action=get_message W GET action=get_message { id: int, refetch_body?: 0/1 } Returns the full message.
?action=get_thread R every message in the anchor message's conversation (same account + gmail_thread_id), oldest first, WITHOUT bodies (the client opens individual messages via get_message).
?action=list_accounts R
?action=list_assignable R GET list_assignable Returns {users:[{username,role}], roles:[...]} scoped to the caller's org.
?action=list_autoreply_rules R List the auto-reply rules for one company, ordered for engine precedence (priority, id).
?action=list_filters R GET list_filters Returns all filters in the caller's org, each with its conditions and assignments arrays.
?action=list_messages W GET action=list_messages Query params: site_id (optional, recommended) limit to a company franchise_id (optional) null means company-wide account_ids (optional CSV) limit to specific accounts search (
?action=list_templates R List the reusable email-reply templates for one company.
?action=mark_message W POST action=mark_message { id: int, is_unread?: bool, is_starred?: bool, is_trashed?: bool } Updates the local DB immediately AND issues the corresponding IMAP flag change so the server state matches.
?action=mark_messages W POST action=mark_messages Flags (any subset, >= 1 required — same semantics as mark_message): { is_unread?: bool, is_starred?: bool, is_trashed?: bool } Selector — EXACTLY ONE of: { ids: int[] } expli
?action=save_autoreply_rule W Create or update an auto-reply rule (id=0/absent -> insert; id>0 -> update, scoped to company_id). template_id must belong to the caller's company_id -- blocks a rule pointing at another company's tem
?action=save_filter W POST save_filter Body params: id (0=create), name, match_type, conditions (JSON array).
?action=save_template W Create or update a template (id=0/absent -> insert; id>0 -> update, scoped to company_id).
?action=send_message W CRM Email Send — compose, reply, forward via per-account SMTP.
?action=set_active W
?action=set_assignments W POST set_assignments Body params: filter_id, assignments (JSON array of {principal_type, principal_value}).
?action=sync W CRM Email Sync — IMAP pull, message storage, and list/get/mark actions.
?action=test_connection R Probe whether we can actually reach the mail provider for a saved account.
?action=test_credentials R Test IMAP credentials supplied in the request body, WITHOUT saving them.
?action=update_account W
crm/email_cron.php CRM Email — periodic sync cron runner. X-API-Token (per action; ?action=public is anonymous)

Single-purpose endpoint — no ?action= dispatch.

crm/email_filters.php CRM Email Filters — tables + CRUD + privilege gate (Task 1). X-API-Token company-scopedrole-gated
actiondescription
?action=contains R
?action=delete_filter W POST delete_filter Body param: id Cascade deletes conditions + assignments via FK.
?action=domain R
?action=equals R Resolve company IDs to the email-account IDs that belong to them, via the same 3-leg mapping listMessagesAction uses (direct company_id, franchise→company, or wordpress site→group→company).
?action=list_assignable W GET list_assignable Returns {users:[{username,role}], roles:[...]} scoped to the caller's org.
?action=list_filters W GET list_filters Returns all filters in the caller's org, each with its conditions and assignments arrays.
?action=save_filter W POST save_filter Body params: id (0=create), name, match_type, conditions (JSON array).
?action=set_assignments W POST set_assignments Body params: filter_id, assignments (JSON array of {principal_type, principal_value}).
crm/estimates.php CRM Estimates API X-API-Token company-scopedrole-gated
actiondescription
?action=check_inspection_estimate R
?action=convert_to_invoice W Convert to invoice
?action=create W Create estimate with items
?action=create_from_inspection W
?action=delete W Delete estimate
?action=duplicate W Duplicate estimate
?action=get W Get single estimate with items
?action=history W Log a CRM activity / /** Activity-log rows for one record, whatever kind it is.
?action=list W Paginated estimate list
?action=recalculate W Recalculate totals
?action=update W Update estimate with items
?action=update_status W Quick status change
crm/franchises.php CRM Franchises API X-API-Token company-scopedrole-gated
actiondescription
?action=create W Create new franchise (developer/admin only)
?action=delete W Delete franchise (developer only)
?action=get R Get single franchise with company info
?action=list R List franchises for a company
?action=update W Update franchise (franchise manager+ access)
crm/import_workiz.php Workiz Data Import - Estimates & Invoices X-API-Token company-scoped
actiondescription
?action=import_estimates W
?action=import_invoices W
?action=stats R
crm/index.php CRM API - Main Router & Table Setup X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

crm/inventory.php CRM Inventory API X-API-Token company-scopedrole-gated
actiondescription
?action=dashboard_stats R stock valuation,
?action=delete_category W delete a category (management; rejected at scope=org)
?action=delete_inventory_client W
?action=delete_item W delete an item (is_active=0; management; rejected at scope=org)
?action=delete_item_image W POST ?action=delete_item_image&image_id= — remove one gallery image.
?action=delete_supplier W ── Phase 2: Purchase Orders ────────────────────────────────────
?action=fulfill_sale W
?action=get_purchase_order R
?action=get_sale R
?action=list_categories R
?action=list_inventory_clients R
?action=list_item_images R GET ?action=list_item_images&item_id= — viewer-gated gallery read.
?action=list_items R
?action=list_job_usage R GET ?action=list_job_usage&job_id=&company_id= — items consumed on a job.
?action=list_purchase_orders R
?action=list_sales R
?action=list_suppliers R
?action=movement_history R
?action=receive_po W ── Inventory clients (separate buyer list) ─────────────────────
?action=record_movement W
?action=remove_item_image W clear image_path + unlink file (management)
?action=reorder_item_images W POST ?action=reorder_item_images — item_id + ordered=[imageIds].
?action=save_category W
?action=save_inventory_client W
?action=save_item W
?action=save_purchase_order W
?action=save_sale W
?action=save_supplier W
?action=search_regular_clients R GET ?action=search_regular_clients&company_id=&search= — read-only lookup of crm_clients for the "link to an existing client" autofill.
?action=set_po_status W
?action=set_sale_payment W
?action=set_sale_status W
?action=stock_levels R
?action=upload_item_image W product image (management, ≤5MB)
crm/invoices.php CRM Invoices API X-API-Token company-scopedrole-gated
actiondescription
?action=create W Create invoice with items
?action=delete W Delete invoice
?action=delete_payment W Delete a payment
?action=duplicate W Duplicate invoice
?action=get W Get single invoice with items + payments
?action=history W Log a CRM activity / /** Activity-log rows for one record, whatever kind it is.
?action=list W Paginated invoice list
?action=list_by_client W One row per client with their invoice totals, for the Invoices > By Client sub-tab.
?action=record_payment W Record a payment
?action=update W Update invoice with items
?action=update_status W Quick status change
?action=void W Void an invoice
crm/job_activity.php CRM Job Activity Timeline API X-API-Token company-scoped
actiondescription
?action=add_note W Add a manual note to a job's timeline.
?action=feed R Return paginated timeline rows for a job, newest first.
?action=log W Handle a POST log request.
?action=summary R Return counts per activity_type for a single job.
crm/jobs.php CRM Jobs API X-API-Token company-scopedrole-gated
actiondescription
?action=assign_tech W Assign technician to job
?action=calendar W Jobs for date range (calendar)
?action=create W Create new job
?action=delete W Archive/delete job
?action=get W Get single job with assignments/client
?action=job_sources W Job-source options for the Jobs form's picker.
?action=lifecycle W Ordered stage/progress pipeline for a job
?action=lifecycle_recent W Latest jobs + their lifecycle pipelines (Timeline tab)
?action=list W Paginated job list
?action=map_jobs W Returns open jobs with coordinates for the Field Map overview.
?action=pipeline W Jobs grouped by status (kanban)
?action=resolve_franchise W Which franchise covers a postal code, for the Jobs form to preselect as soon as a client (or address) is chosen.
?action=set_job_cost W Set item_cost/tech_cost (non-Workiz jobs, management+)
?action=slot_capacity W Remaining seats per time block for a (company, franchise, date).
?action=unassign_tech W Remove technician from job
?action=update W Update job
?action=update_status W Quick status change
crm/lead_processor.php CRM Lead Processor Integration API X-API-Token company-scoped
actiondescription
?action=config R
?action=list R
?action=poll_leads W
?action=save_config W
?action=stats R
crm/lead_processor_helpers.php api/crm/lead_processor_helpers.php X-API-Token

Single-purpose endpoint — no ?action= dispatch.

crm/leads.php CRM Leads API X-API-Token company-scopedrole-gated
actiondescription
?action=convert_to_job W Convert lead to job
?action=create W Create new lead
?action=delete W Archive/delete lead
?action=get W Get single lead
?action=list W Paginated lead list
?action=mark_lost W Mark lead as lost with reason
?action=mark_spam W Mark lead as spam (form abuse)
?action=unread_count W Get count of new leads created in the last 7 days.
?action=update W Update lead
?action=update_status W Quick status change
crm/my_schedule.php My Schedule API — Personal job schedule for technicians. X-API-Token company-scoped
actiondescription
?action=check_new_assignments R
?action=get_my_schedule R
?action=update_tech_notes W
crm/onboarding.php CRM-side New-Hire Onboarding API (authenticated, manager-gated) X-API-Token company-scopedrole-gated
actiondescription
?action=cancel W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=complete_tax W Read a request value from the query string / POST form, falling back to the JSON body.
?action=create W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=get W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=get_contract_template W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=get_employer_signature W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=get_onboarding_config W Read a request value from the query string / POST form, falling back to the JSON body.
?action=hr_document W Read a request value from the query string / POST form, falling back to the JSON body.
?action=hr_record W Read a request value from the query string / POST form, falling back to the JSON body.
?action=list W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=list_contracts R The per-category agreement PDF dir + slug mapping, matching the hire-side `obh_contract_for()` in api/onboarding.php.
?action=list_roles W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=my_onboarding W Is this user exempt from the onboarding reminder/lock? 'developer' / platform authority is the ONLY hardcoded exemption — it is the role that edits the exempt-role setting, so it must never be lockabl
?action=my_tax_status R
?action=permanent_delete W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=regen_bundle W Ensure the onboarding_config table exists.
?action=regenerate W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=resend R
?action=save_onboarding_config W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=self_start W Read a request value from the query string / POST form, falling back to the JSON body.
?action=set_employer_signature W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=set_enforcement W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
?action=test_create_invite W Base-aware gate keyed by username: resolves the user's (role, org_id) once per request (static cache), then roleInSet().
?action=test_delivery W Deliver the code over the requested channel(s).
?action=update_regen_terms W Does this user have CRM access to this company? Mirrors the gate the rest of the CRM uses (crm_company_access row, or a manager-class global role).
?action=upgrade_invite W Parsed JSON request body, read from php://input exactly once and cached (php://input is not reliably re-readable across SAPIs).
crm/payroll.php CRM Payroll API X-API-Token company-scoped
actiondescription
?action=assign_employee W Assign employee to payroll
?action=available_users R Users not yet on payroll
?action=earnings R Earnings report
?action=employees R List payroll employees
?action=remove_employee W Remove from payroll
?action=summary R Payroll summary
?action=update_employee W Update employee rate/info
crm/reports.php CRM Reports API X-API-Token company-scopedrole-gated
actiondescription
?action=aging_invoices R Overdue invoice report
?action=breakdown R
?action=capacity R ─── Reports added 2026-07-20 (Onboarding / Work Hours sub-tabs) ────
?action=coming_up R
?action=dashboard R Dashboard summary metrics
?action=estimates_funnel R
?action=franchise_comparison R Compare franchises
?action=inspections R
?action=job_costing_detail R
?action=job_costing_list R
?action=job_costing_summary R
?action=jobs_summary R Job completion stats
?action=lead_conversion R Lead source effectiveness
?action=onboarding_summary R Onboarding invite/completion aggregates
?action=pipeline_value R Value in each stage
?action=revenue R Revenue by date range
?action=sales_series R ─── Reports added 2026-05-08 to cover the new tabs (Inspections,
?action=services R
?action=technician_performance R Per-tech stats
?action=today R
?action=training R
?action=web_leads_summary R Web chat + form lead counts (windowed)
?action=work_hours_summary R Per-user / per-role clocked-time totals
crm/scheduling.php CRM Scheduling API X-API-Token company-scoped
actiondescription
?action=apply_recommendation W Apply route recommendation assignments
?action=board W MM-DD - Full scheduling board
?action=board_month R
?action=board_week R
?action=create_category W
?action=create_org_category W Create an org-level category.
?action=create_slot W Create a time slot
?action=delete_availability W Remove availability override
?action=delete_category W Org-level Job Categories
?action=delete_org_category W Soft-delete an org-level category.
?action=delete_slot W Soft-delete a time slot
?action=get_availability R Availability overrides
?action=get_categories R List all categories for a company — with org-level fallback via effectiveCategories().
?action=get_client_sms_template R Get an SMS template from settings, or return the default. / // ============================================================================ // CLIENT SMS // ===========================================
?action=get_org_categories R List org-level categories (admin/owner only).
?action=get_org_settings W Return scheduling org-level overrides from crm_org_settings.
?action=get_settings R Get scheduling settings for a company.
?action=get_slots R Active slot definitions
?action=get_tech_skills R
?action=move_job W Move job to different slot/tech/date
?action=org_slot_capacity R Every franchise in the org with its per-block job capacity, plus the company and org numbers it would inherit.
?action=recommend_route R Route recommendation for single tech
?action=recommend_route_all R Route recommendations for all techs
?action=respond_to_schedule W Technician accepts or denies a pending job slot assignment.
?action=schedule_job W Assign job to tech+slot+date
?action=seed_default_categories W Technician Skills
?action=seed_default_slots W Seed 5 default time slots
?action=send_client_sms W Send SMS to client for a scheduled job.
?action=send_day_of_reminders W Send day-of reminder SMS to all clients with accepted jobs for today.
?action=set_availability W Set tech availability for a date
?action=set_tech_skills R
?action=unschedule_job W Remove slot assignment
?action=update_category W
?action=update_org_category W Update an org-level category.
?action=update_org_settings W Upsert scheduling org-level overrides into crm_org_settings.
?action=update_settings W Update scheduling settings for a company.
?action=update_slot W Update a time slot
crm/service_area_zips.php CRM — Service-area ↔ ZIP-code mapping (suggestion #3, Trey). X-API-Token company-scoped
actiondescription
?action=list R
?action=lookup R
?action=rebuild W Re-derive the map from the full Workiz job history.
?action=remove W
?action=set W
crm/service_areas.php service_areas.php — CRM service areas (Workiz calls them "metro areas"). X-API-Token company-scoped
actiondescription
?action=ambiguous_zips R Zips mapped to MORE THAN ONE service area.
?action=assign_zips W Map zips onto an area.
?action=create W A native (non-Workiz) area.
?action=list R service_areas.php — CRM service areas (Workiz calls them "metro areas").
?action=remove_zips W Unmap zips from an area.
?action=update W Rename, reassign the franchise, or deactivate.
crm/services.php CRM Services API X-API-Token company-scoped
actiondescription
?action=categories R Get distinct categories
?action=create W Create new service
?action=delete W Delete service
?action=get R Get single service
?action=import W Bulk import services
?action=list R Paginated service list
?action=remove_image W Remove cover image
?action=update W Update service
?action=upload_image W Upload cover image (multipart)
crm/settings.php CRM Settings API - Company Settings, Custom Statuses & Custom Fields X-API-Token company-scoped
actiondescription
?action=api_catalog R The generated catalog of every endpoint + action the app can call (api/shared/api_catalog.json, emitted by scripts/gen_api_docs.js).
?action=create_custom_field W Create custom field
?action=create_org_status W Create an org-default status.
?action=create_status W Create custom status
?action=custom_fields R Get custom fields
?action=delete_custom_field W Delete custom field
?action=delete_org_setting W Delete an org-level setting
?action=delete_org_status W Delete an org-default status.
?action=delete_setting W Delete a company-level setting row (admin-gated)
?action=delete_status W Delete a status
?action=get R Get all settings for a company
?action=get_job_workflow R The effective workflow for a company by key (resolution in crmWorkflowEffective, crm/index.php).
?action=get_org_settings R Get all org-level settings (resolved org_id from company_id param)
?action=get_workflow R The effective workflow for a company by key (resolution in crmWorkflowEffective, crm/index.php).
?action=job_workflow_templates R Built-in workflow templates the builder UI offers as starting points.
?action=list_workflows R Every workflow visible to a company: the seeded registry (job_flow, inspection_flow, and the four status-mirror flows) plus any custom workflow_* settings.
?action=org_statuses R Get org-default statuses for an entity type (org_id, entity_type).
?action=reorder_org_statuses W Reorder org-default statuses for an entity type.
?action=reorder_statuses W Reorder statuses
?action=statuses R Get custom statuses
?action=update W Update a setting
?action=update_custom_field W Update custom field
?action=update_org_setting W Upsert an org-level setting
?action=update_org_status W Update an org-default status.
?action=update_status W Update a status
crm/sidebar_badges.php CRM Sidebar Badges X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

crm/team_sync.php api/crm/team_sync.php — A1 ↔ Workiz person mapping, CRM-authenticated. X-API-Token company-scoped
actiondescription
?action=overview R Who is kept OUT of the scheduling roster despite holding an assignable role.
?action=set_mapping W Gate a WRITE behind a tab-matrix ACTION KEY (Jose's ruling 2026-08-16, reaffirmed 2026-08-20: "if someone has access to said tab, they should be able to do EVERYTHING inside said tab").
crm/tools.php CRM Tools & Equipment API X-API-Token company-scopedrole-gated
actiondescription
?action=add_stock W tool_id, company_id, qty.
?action=assign_tool W
?action=backfill_assignments W POST backfill_assignments company_id — one-time reconciliation (manage).
?action=dashboard_stats R company_id [, franchise_id].
?action=delete_tool W
?action=list_assignments R
?action=list_technicians R
?action=list_tools R
?action=return_assignment W
?action=save_tool W
?action=seed_from_onboarding W
crm/tools_onboarding.php Tools & Equipment — onboarding hooks (dependency-free). UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

crm/vehicle_reminders.php Vehicle service reminders — texts the assigned driver before an oil change UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

crm/vehicles.php CRM Vehicles API X-API-Token company-scopedrole-gated
actiondescription
?action=assign_vehicle W
?action=assignment_history R
?action=dashboard_stats R
?action=delete_file W
?action=delete_payment W
?action=delete_service_log W
?action=delete_vehicle W delete, is_active=0 (vehicles_delete)
?action=get_vehicle R
?action=list_files R
?action=list_payments R
?action=list_service_logs R
?action=list_vehicles R
?action=reorder_photos W
?action=save_payment W
?action=save_service_log W
?action=save_vehicle W
?action=unassign_vehicle W
?action=upload_file W Upload a photo or document for a vehicle.

integrations — 49 endpoints

_cache_invalidation_helpers.php Cache Invalidation Helpers — server side of the Layer C webhook HMAC signature

Single-purpose endpoint — no ?action= dispatch.

a1tools/boards.php Sunday board directory for A1 Leads (A1 Leads → A1 Tools wire). HMAC signature company-scoped

Single-purpose endpoint — no ?action= dispatch.

app_update.php Manages app updates - check for updates, push updates to all clients X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=cancel R
?action=check R
?action=check_minimum R
?action=get_version_settings R
?action=push R
?action=set_auto_update R
?action=set_version_settings R
?action=should_auto_update R
?action=status R
chat_groups.php Handles group chat functionality. X-API-Token company-scopedrole-gated
actiondescription
?action=add_member R
?action=create R
?action=delete R
?action=get_group R
?action=get_messages R
?action=list R
?action=mark_read R
?action=remove_member R
?action=send_message R
?action=set_member_role R
?action=total_unread R
?action=update R
chat_messages.php Handles persistent chat messages between users. X-API-Token company-scopedrole-gated
actiondescription
?action=get_conversation R
?action=get_conversations R
?action=get_unread R
?action=get_unread_count R
?action=mark_read R
?action=send R
company_integrations.php X-API-Token company-scoped
actiondescription
?action=delete R
?action=get R
?action=save R
?action=status R
config.php Centralized Configuration File X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

ekomi_integration.php eKomi integration — per-company config + account-snapshot endpoint. X-API-Token company-scoped
actiondescription
?action=get_config R eKomi integration — per-company config + account-snapshot endpoint.
?action=get_overview R eKomi integration — per-company config + account-snapshot endpoint.
?action=get_recipients R eKomi integration — per-company config + account-snapshot endpoint.
?action=get_reviews R eKomi integration — per-company config + account-snapshot endpoint.
?action=get_status R eKomi integration — per-company config + account-snapshot endpoint.
?action=save_config W eKomi integration — per-company config + account-snapshot endpoint.
?action=set_enabled W eKomi integration — per-company config + account-snapshot endpoint.
?action=test_connection R eKomi integration — per-company config + account-snapshot endpoint.
env_compile.php env_compile.php — One-shot generator for `.env.php`. upload secret

Single-purpose endpoint — no ?action= dispatch.

extract_web.php Web Deploy Extraction API upload secret

Single-purpose endpoint — no ?action= dispatch.

guide.php In-App Guidance API (2026-07-28). X-API-Token role-gated
actiondescription
?action=delete_step W
?action=delete_tour W
?action=delete_video W
?action=for_tab R Runtime read: the published tour + published videos for one tab.
?action=list_tours R
?action=list_videos R
?action=reorder_steps W
?action=save_step W
?action=save_tour W
?action=save_video W
?action=stream_video R Stream an uploaded video, with HTTP Range support.
hr_employees.php Human Resources API X-API-Token company-scopedrole-gated
actiondescription
?action=available_users W Get users not linked to any employee
?action=create W
?action=delete W Delete employee (soft delete - sets is_active = 0)
?action=delete_document W Delete document
?action=get W Get single employee with documents
?action=get_document W
?action=get_document_data W Returns the file as base64 JSON instead of streaming it.
?action=list W List all employees
?action=list_all_documents W Company-wide HR document library (Phase 6B).
?action=update W Update employee
?action=upload_document W Upload document
?action=upload_picture W Upload profile picture for employee
?action=version R
integration_health.php api/integration_health.php — "what is misconfigured, and where". X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

integrations_status.php Integration Status API X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

invoice_items.php Invoice Items API X-API-Token company-scoped
actiondescription
?action=categories R List item categories
?action=create W Create custom item (local only)
?action=delete W Delete custom item
?action=get R Get single item
?action=list R List all invoice items
?action=search R Search items by name
?action=sync W Sync items from Workiz
?action=update W Update item
lookup.php Phone-number data-quality endpoint — Twilio Lookup v2 (validation, X-API-Token company-scoped
actiondescription
?action=batch_check_reassigned W Phone-number data-quality endpoint — Twilio Lookup v2 (validation, line type intelligence, reassigned number) with a global result cache.
?action=check_send_guard R Line types that definitively cannot receive SMS — a landline has no SMS capability at all (the exact pain point in the task brief).
?action=lookup_client_phones W Resolve a client's phone + phone_secondary through lookupPhoneNumber() (cache-aware, never throws on Twilio unavailability) and persist the badge fields back onto crm_clients.
?action=lookup_number W Validate + classify one number, cache-first.
mailchimp_integration.php Mailchimp Integration API X-API-Token company-scoped
actiondescription
?action=get_config R
?action=save_config W
?action=test_connection W
newsletters/cron.php Newsletters — scheduled-send cron runner. URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

newsletters/index.php Newsletters API — campaigns, templates, segment preview. X-API-Token company-scopedrole-gated
actiondescription
?action=add_suppression W
?action=approve_campaign W Approve a campaign, optionally scheduling it.
?action=cancel_campaign W
?action=delete_campaign W
?action=delete_template W
?action=get_campaign W
?action=job_statuses W The job status keys this company's jobs ACTUALLY carry, with live counts.
?action=list_campaigns W
?action=list_suppressions W
?action=list_templates W
?action=preview_segment W Live recipient count for a segment under construction.
?action=remove_suppression W Remove a suppression.
?action=save_campaign W Create or update a campaign.
?action=save_template W
?action=segment_sample W First N recipients, so the review step shows real names rather than a number.
?action=submit_for_approval W
newsletters/public.php Newsletters — recipient-facing routes. UNAUTHENTICATED BY NECESSITY. X-API-Token (per action; ?action=public is anonymous) company-scoped
actiondescription
?action=click W Record a click and forward.
?action=pixel W 1x1 transparent GIF, always returned — a broken image in the email would be worse than untracked.
?action=unsubscribe W Opt the recipient out and show a plain confirmation page.
newsletters/send.php Newsletters — sending. X-API-Token company-scoped
actiondescription
?action=drain W
?action=push_to_mailchimp W Push a CRM segment into the Mailchimp audience without sending anything.
?action=send_status W
?action=send_test W Send one copy to a nominated address for eyeballing.
?action=start_send W Freeze the audience and begin sending (or arm a scheduled send).
newsletters/upload.php Newsletters — inline image upload. X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

office_map.php Office Map API v2 X-API-Token company-scopedrole-gated
actiondescription
?action=add_computer R
?action=add_wall R
?action=assign R
?action=batch_update_positions R
?action=clear_walls R
?action=command_executed R
?action=debug_user R
?action=delete_wall R
?action=get_all R
?action=get_background R
?action=get_command_history R
?action=get_users R
?action=heartbeat R
?action=remote_command R
?action=remove_computer R
?action=set_background R
?action=update_name R
?action=update_position R
?action=update_wall R
profile/picture.php Handles profile picture upload, retrieval, and deletion. UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

push_notifications.php Push Notifications API X-API-Token role-gated
actiondescription
?action=clear_all W Clear all notifications
?action=get_config R Get FCM configuration
?action=get_history W Get notification history
?action=get_stats R Get push notification statistics
?action=mark_read W Mark notification as read
?action=register_token W Register FCM token
?action=save_config W Save FCM configuration
?action=send_notification W Send to specific users
?action=send_to_all W Send to all users
?action=send_to_role W Send to all users with role
?action=unregister_token W Unregister FCM token
route_optimization.php Route Optimization API X-API-Token
actiondescription
?action=get_config R Get route optimization config
?action=get_stats R Route optimization statistics
?action=save_config W Save route optimization config
search.php Lightweight global search endpoint used by the in-app command palette X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

smtp_config.php SMTP Configuration API X-API-Token company-scopedrole-gated
actiondescription
?action=get R Read stays at the identity floor above: getConfig() already blanks
?action=save W SMTP Configuration API Manages SMTP settings for email sending.
?action=test W SMTP Configuration API Manages SMTP settings for email sending.
testing_ground.php Testing Ground API (2026-07-28). X-API-Token company-scoped
actiondescription
?action=end W POST end {token} — mark one testing session's token row inactive.
?action=impersonate W POST impersonate {role_key} — ensure the testing account exists, then mint a short-lived bearer token for it and hand back the identity the client needs to render the app as that user.
?action=list R Testing Ground API (2026-07-28).
thumbtack/index.php Thumbtack integration — CRM-facing endpoint. X-API-Token (per action; ?action=public is anonymous) company-scopedrole-gated
actiondescription
?action=businesses W
?action=classify_lead W Classify one lead.
?action=delete_credentials W Drop this company's stored credentials; the env fallback (if any) resumes.
?action=disconnect W
?action=draft_reply W Draft a reply.
?action=events W Credentials (stored per company, encrypted).
?action=lead R
?action=leads R
?action=link_business W
?action=mark_promoted W Record that a lead became a CRM client (and optionally a job).
?action=mark_read W
?action=messages W The thread for one lead.
?action=oauth_callback W Browser redirect target.
?action=oauth_start W
?action=phone_numbers W
?action=push_job_status W Push a job-status signal by hand.
?action=respond_review W Phase 4 — messages.
?action=reviews R
?action=save_credentials W Store this company's Thumbtack app credentials.
?action=send_message W Send a message to the customer.
?action=status W
?action=sync_phone_numbers W Reconcile the registered numbers with the list the caller wants registered.
?action=sync_reviews W Backfill from Thumbtack.
?action=test_lead W
?action=unlink_business W
thumbtack/webhook.php Thumbtack inbound webhook receiver. UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

tiles.php Map-tile caching proxy. URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

twilio_integration.php Twilio Integration API X-API-Token company-scoped
actiondescription
?action=get_config R
?action=get_phone_numbers W
?action=save_config W
?action=test_connection W Phone Numbers
twilio_media.php Signed-URL serving of one MMS attachment (sms_message_media row). X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

twilio_webhook.php Twilio Inbound SMS Webhook UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

upload_release.php upload_release.php — Accepts installer and web deploy uploads from build_release.ps1 upload secret

Single-purpose endpoint — no ?action= dispatch.

voice.php Spec 0 — app-facing voice endpoint: call list + ownership-gated recording playback. X-API-Token company-scoped
actiondescription
?action=cancel_scheduled_message W Cancel one pending scheduled message.
?action=get_call R Full detail of one call, ownership-checked.
?action=get_call_outcomes R
?action=get_contact_context R The right-hand contact pane: resolved CRM client (if any) + their recent jobs/estimates/invoices + notes.
?action=get_my_phone_settings R The caller's own phone profile for $companyId.
?action=get_thread R The merged call+SMS timeline for one counterparty number, interleaved by timestamp.
?action=get_transcript R Map the sid the CLIENT knows to the sid the transcript is filed under (2026-08-13 — fixing a real bug found on a live call).
?action=get_voice_config R Voice settings for the admin UI.
?action=list_calls R Calls for one company, newest first.
?action=list_numbers R The company's crm_phone_numbers rows enriched with live Twilio data, plus a top-level twilio_unavailable flag (true when credentials aren't configured, or the Twilio call failed for at least one row)
?action=list_scheduled_messages W Company-scoped list of scheduled messages, optionally filtered by status and/or related entity.
?action=list_threads R One row per counterparty phone number, aggregating crm_calls AND sms_message_log for this company.
?action=list_twilio_numbers R Every number on this company's Twilio account (the "import an existing number" surface), each flagged with whether it is already registered in crm_phone_numbers and to which company.
?action=mark_thread_read W Marks every INBOUND, not-yet-read sms_message_log row for one thread as read — the write side of `unread_sms_count`/the thread-list unread dot, neither of which anything previously cleared.
?action=place_call W Spec 0 — Voice Call Control Core helpers.
?action=point_number_to_a1 W Point a company-owned Twilio number's VoiceUrl (AND StatusCallback — see below) at this server's voice_webhook.php.
?action=purchase_number W Buy a number from Twilio, then register it locally and point it at our webhook, in one flow.
?action=recording W Ownership gate for recording playback.
?action=register_number W Register an already-Twilio-owned number for this company.
?action=save_account_credentials R Save account_sid and/or auth_token, MERGING over the shared 'twilio' integration blob — same read-then-array_merge-then-saveCompanyIntegration() pattern as saveVoiceConfig() above and saveTwilioSmsCon
?action=save_my_phone_settings W Save the caller's own phone profile.
?action=save_voice_config R Save fallback_number / recording_enabled / recording_announcement_text, MERGING over the shared 'twilio' integration blob exactly like saveTwilioSmsConfig() (shared/twilio_helpers.php) does for the SM
?action=schedule_message W Schedule a message to a thread's counterparty number, held and sent by Twilio itself (ScheduleType=fixed). $relatedEntityType/$relatedEntityId (e.g. 'job', 123) let a caller later find and cancel this
?action=search_available_numbers W Search Twilio's purchasable US local inventory by area code and/or a contains-pattern.
?action=send_thread_message W Send an SMS (optionally MMS) to a thread's counterparty number from this company's configured number, via the EXISTING sendSms() (shared/twilio_helpers.php) — never reimplemented here.
?action=set_call_outcome R The softphone knows its own <Client> leg SID, which has no crm_calls
?action=unregister_number W Remove a number from crm_phone_numbers ONLY.
?action=update_number W Update label/purpose/assigned_user_id/is_active for a number OWNED by this company.
?action=upload_thread_media W Upload one outbound MMS attachment ahead of sending it.
voice_audio.php Token-serving of one Voice Audio Library file (crm_voice_audio_files row). X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

voice_client.php Softphone backend — in-app Twilio Voice client (see X-API-Token company-scoped
actiondescription
?action=ensure_twiml_app W Idempotent: never creates a second Application for a company. 1.
?action=get_access_token W Mint an Access Token for the AUTHENTICATED caller.
?action=get_softphone_config R Curated summary for the admin UI.
?action=get_twiml_app R Read-only summary — never talks to Twilio (cheap, matches get_voice_config's local-only read).
?action=heartbeat_presence W Shared by register_presence AND heartbeat_presence — both are the same idempotent upsert.
?action=list_colleagues R Every OTHER user this company's dialer may dial internally: id, display name, softphone identity, and whether that identity is registered right now (a single extra indexed isSoftphoneIdentityOnline()
?action=register_presence W Shared by register_presence AND heartbeat_presence — both are the same idempotent upsert.
?action=save_softphone_config R Save api_key_sid + api_key_secret, MERGING over the shared 'twilio' blob — exactly saveVoiceConfig()'s merge pattern (voice_helpers.php): read the existing blob, array_merge() just these two keys on t
?action=unregister_presence W ------------------------------------------------------------------
voice_fallback.php G. Voice failover TwiML — the target of a Twilio number's UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

voice_numbers.php Phone-number lifecycle admin endpoint — search, pricing, purchase, full X-API-Token company-scoped
actiondescription
?action=cancel_port_request W Cancel a port request.
?action=check_portability R Portability check — genuinely API-backed (numbers.twilio.com/v1/Porting/ Portability).
?action=create_port_request W Create a locally-tracked port request (both directions start as pure local tracking).
?action=deactivate_number R Flip crm_phone_numbers.is_active.
?action=get_number_pricing R Full pricing preview for the Setup tab: monthly ownership cost (Pricing API's PhoneNumbers sub-API) + per-minute voice cost (Pricing API's Voice sub-API, v2 — a different major version than PhoneNumbe
?action=get_port_request R Also POST-only by accident, same class as purchase_number/release_number
?action=list_port_requests R All port requests (both directions) for this company, newest first.
?action=purchase_number W Buy a number from Twilio (with optional AddressSid/BundleSid for regulatory-gated countries/number types), register it locally via the existing registerPhoneNumber() (voice_helpers.php — single source
?action=reactivate_number R ------------------------------------------------------------------
?action=release_number W Permanently release a number from Twilio (DELETE IncomingPhoneNumbers).
?action=search_numbers R Rich AvailablePhoneNumbers search across local/toll-free/mobile, with the full filter set from research §A.1 plus vanity-word support.
?action=submit_port_in_to_twilio W Pure validator + request-body builder for submit_port_in_to_twilio — no PDO, no credentials, no network call, so every validation rule (and the exact shape of the constructed body) is unit-testable in
?action=sync_port_status W Refresh a submitted port_in row's status from Twilio (GET, genuinely API-backed).
?action=update_number_messaging_config W Update ONLY messaging-side fields.
?action=update_number_voice_config W Partial-update engine shared by updateNumberVoiceConfig()/ updateNumberMessagingConfig(). $allowedMap is the field set this action MAY change; $forbiddenMap is the OTHER action's field set, rejected o
?action=update_port_request W Manual field update (carrier/notes/status/target_port_date) — the port_out tracking path, and the pre-submission port_in path.
voice_ops.php Voice-operations admin endpoint — Usage Triggers (spend alerts), X-API-Token company-scoped
actiondescription
?action=create_usage_trigger R Twilio's create body validated against the exact enums confirmed live 2026-07-30 (docs: usage/api/usage-trigger).
?action=delete_usage_trigger R ------------------------------------------------------------------
?action=get_amd_default R
?action=get_debugger_alert R ------------------------------------------------------------------
?action=get_live_transcription R Live call transcription (2026-08-13) — the `<Transcription>` TwiML verb.
?action=get_missed_call_text R Missed-call text-back (2026-08-13).
?action=get_usage_trigger R POST-only by accident, same class as voice_numbers.php's
?action=list_debugger_alerts R List Debugger alerts, filterable by log level and date range (Twilio caps both StartDate/EndDate at 30 days old — not re-enforced here, Twilio's own 400 on an out-of-range date is passed through as-is
?action=list_usage_triggers R
?action=save_amd_default W Missed-call text-back (2026-08-13).
?action=save_live_transcription W
?action=save_missed_call_text W Absent (not merely empty) means "leave the stored template alone" —
?action=set_number_fallback_to_a1 W Point a company-owned Twilio number's VoiceFallbackUrl at this server's voice_fallback.php (independent of voice_webhook.php by design — see that file's module doc comment for why).
?action=update_usage_trigger W Twilio only accepts FriendlyName/CallbackUrl/CallbackMethod on a Usage Trigger UPDATE — the threshold-defining fields (UsageCategory, TriggerValue, TriggerBy, Recurring) are immutable once created per
voice_routing.php Voice Call Control Core — Routing / IVR / business-hours / voicemail admin X-API-Token company-scoped
actiondescription
?action=check_business_hours R Is $companyId's business open at instant $at? Precedence (highest first), matching the twilio-professional-services/ flex-schedule-manager model cited in the research (§E): manual override -> date_ove
?action=create_ivr_menu W
?action=delete_audio W Refuses (409, never silently succeeds) to delete a file still referenced by any greeting — deleting audio an IVR node or voicemail box depends on would silently break that greeting the next time it's
?action=delete_business_hours_schedule W
?action=delete_ivr_menu W
?action=delete_ivr_node W ------------------------------------------------------------------
?action=delete_ring_group W ------------------------------------------------------------------
?action=delete_voicemail_box W
?action=download_audio W Authenticated byte-fetch for in-app preview playback ONLY — the
?action=get_business_hours_schedule R
?action=get_ivr_menu R Full tree for the admin editor: menu + every node + every node's actions.
?action=get_ring_group R
?action=get_tts_voice_catalogue R full: array<int,array{voice:string,language:string,provider:string,tier:string,label:string}>}
?action=get_voice_routing_config R null when the company has never configured routing at all (legacy flow).
?action=get_voicemail_box R
?action=get_voicemail_transcript W Ownership gate for recording playback.
?action=list_audio_library R
?action=list_business_hours_schedules R
?action=list_ivr_menus R
?action=list_ring_groups R
?action=list_voicemail_boxes R
?action=rename_audio W
?action=save_business_hours_schedule W Nested save payloads arrive as a JSON-encoded string in a single POST field — the project's POST wire contract is flat form fields, not a JSON body, so a nested array has to be serialized client-side
?action=save_ivr_node W Nested save payloads arrive as a JSON-encoded string in a single POST field — the project's POST wire contract is flat form fields, not a JSON body, so a nested array has to be serialized client-side
?action=save_ring_group W Nested save payloads arrive as a JSON-encoded string in a single POST field — the project's POST wire contract is flat form fields, not a JSON body, so a nested array has to be serialized client-side
?action=save_voice_routing_config W Partial update, same convention as voice_helpers.php::updatePhoneNumber(): a key ABSENT from $fields keeps its current stored value; a key present with null/'' explicitly CLEARS that destination; a ke
?action=save_voicemail_box W Nested save payloads arrive as a JSON-encoded string in a single POST field — the project's POST wire contract is flat form fields, not a JSON body, so a nested array has to be serialized client-side
?action=update_ivr_menu W
?action=upload_audio W Admin-tier + company-scoped, per the build brief: this writes to
voice_trust.php Caller-identity/trust admin endpoint — SHAKEN/STIR attestation reporting, X-API-Token company-scoped
actiondescription
?action=assign_number_to_trust_product W Attach a company-owned phone number to a company-owned Trust Product (Channel Endpoint Assignment).
?action=delete_spam_remediation_entry W
?action=get_attestation_summary R Aggregate attestation mix over a date range — the "silent degradation from A to B/C is visible rather than invisible" report the task calls for.
?action=get_trust_status W Combined snapshot for the admin UI: both registration types (each created as a not_started placeholder on first read so the UI always has a row to render), plus a spam-remediation summary count by sta
?action=list_spam_remediation R All tracked entries for a company, optionally filtered to one number.
?action=save_spam_remediation_entry W Upsert one (phone_number_id, carrier) tracking row — the entire point of this table is "log what an admin observed and what they did about it", so this is the single write path for both creating and u
?action=start_cnam_registration W Start (or re-start, if the prior attempt was rejected/abandoned) a CNAM registration: create the Trust Product, an End User carrying the display name, and the Entity Assignment linking it to the given
?action=start_voice_integrity_registration W Same shape as startCnamRegistration() but for Voice Integrity — no display name / End User, just the Trust Product + Entity Assignment.
?action=submit_trust_registration_for_review W Move a Trust Product from draft to pending-review.
?action=sync_trust_registration W Refresh a registration's status from Twilio.
voice_webhook.php Twilio Voice Webhook (Spec 0). UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

voice_webhook_handler.php Spec 0 — inbound voice webhook logic. UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

wordpress_featured_images.php Bulk featured-image management for fleet WordPress sites X-API-Token company-scopedrole-gated
actiondescription
?action=bulk_set_featured W Set featured_media on a batch of pages (max 50 per call).
?action=get_pages W Enumerate every published page on the site (id, title, link, featured_media).
?action=upload_media W Upload one base64 image to the site's media library.
wordpress_helpers.php WordPress Helper Functions X-API-Token company-scoped

Single-purpose endpoint — no ?action= dispatch.

wordpress_sites.php WordPress Sites Management API X-API-Token company-scopedrole-gated
actiondescription
?action=delete W
?action=delete_group W Group social media defaults endpoints
?action=get W
?action=get_group W
?action=get_group_social W
?action=list W
?action=list_groups W
?action=save W
?action=save_group W
?action=save_group_social W
?action=test W Group endpoints

monitoring — 16 endpoints

alerts.php Standalone alerts API that properly handles attachments. X-API-Token
actiondescription
?action=check R
?action=debug R
?action=poll R
?action=test R
?action=testpoll R
alerts_heartbeat.php Presence heartbeat — plain-PHP replacement for the WordPress REST route X-API-Token

Single-purpose endpoint — no ?action= dispatch.

capture_protection_settings.php Capture-Protection exempt-role settings — LEGACY COMPATIBILITY endpoint X-API-Token role-gated
actiondescription
?action=get W The `get` response payload.
?action=set R SC1 (2026-07-17): the global exempt list is retired — screen
compliance.php Compliance System API X-API-Token role-gated
actiondescription
?action=check_compliance W Check and auto clock-out inactive users
?action=clear_logs W Clear compliance logs
?action=delete_log W Delete a single compliance log entry
?action=extend_timeout W Extend auto clock-out timeout for a user
?action=heartbeat W User sends heartbeat (called by app)
?action=logs R Get compliance action logs
?action=settings W Get compliance settings
?action=status W Get compliance status for all users
?action=test R Identity comes from the verified bearer, not a request parameter.
?action=update_settings W Update compliance settings
crash_reports.php Crash Reports API X-API-Token company-scopedrole-gated
actiondescription
?action=delete W Delete a crash report
?action=delete_all W Delete all resolved crash reports
?action=delete_all_reports W Delete ALL crash reports
?action=get R Get a single crash report detail
?action=list R List all crash reports (admin)
?action=resolve W Mark a crash report as resolved
?action=resolve_all W Mark all unresolved crash reports as resolved
?action=stats R Get crash statistics summary
?action=submit W Submit a new crash report
?action=unresolve_all W Mark all resolved crash reports as unresolved
debug_log.php Debug Log Endpoint X-API-Token

Single-purpose endpoint — no ?action= dispatch.

health.php Health check endpoint. anonymous

Single-purpose endpoint — no ?action= dispatch.

heartbeat_monitor.php Heartbeat Monitor API - Layer 3 of the multi-layered restart system X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=check R
?action=clear_old_alerts R
?action=get_alerts R
?action=get_offline_users R
?action=get_summary R
?action=resolve_alert R
lock_screen_exceptions.php Lock Screen Exceptions API X-API-Token role-gated
actiondescription
?action=add W Add exception for user
?action=check R Check if user has exception
?action=list R List all exceptions
?action=remove W Remove exception for user
monitoring.php A1 Tools Monitoring API X-API-Token role-gated
actiondescription
?action=ack_relay_input W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=cleanup W Integer value of one app_settings row, or $default when unset / blank / non-numeric / DB error.
?action=create_session W A1 Tools Monitoring API Coordination server for the monitoring system: - Peer registry (IP, port, screen info per machine) - Session management (auth tokens for P2P connections) - Screenshot storage a
?action=end_session W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=get_screenshot W A1 Tools Monitoring API Coordination server for the monitoring system: - Peer registry (IP, port, screen info per machine) - Session management (auth tokens for P2P connections) - Screenshot storage a
?action=list_screenshots W A1 Tools Monitoring API Coordination server for the monitoring system: - Peer registry (IP, port, screen info per machine) - Session management (auth tokens for P2P connections) - Screenshot storage a
?action=poll_relay_frame W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=poll_relay_input R Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=register_peer W Called by each app during heartbeat — no admin check needed
?action=send_relay_input W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=update_session W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=upload_relay_frame W Load an ACTIVE session row and prove the authenticated caller is a party to it.
?action=upload_screenshot W Get the screenshots storage directory, creating it if needed.
?action=validate_session W Called by target machine to validate an incoming P2P connection
observability/log_alerter.php Structured-log → Slack alerter. URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

privacy_exclusions.php Privacy Exclusions API X-API-Token role-gated
actiondescription
?action=add W Add exclusion
?action=check R Check if program is excluded
?action=list R List all exclusions
?action=remove W Remove exclusion by ID
?action=suggestions R Get suggested programs based on common usage across users
remote_files.php Remote file access — developer-only command queue. X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=cancel R
?action=complete R
?action=download R
?action=enqueue R
?action=enqueue_write R
?action=fetch_upload R
?action=get_result R
?action=pending R
remote_monitoring.php Remote Monitoring API X-API-Token role-gated
actiondescription
?action=ack_command W Acknowledge command execution
?action=get_commands R Target polls for pending commands
?action=get_latest W Get the latest screenshot
?action=get_screenshot W Get a specific screenshot
?action=get_status W Get target's online status
?action=heartbeat W Target sends heartbeat with status
?action=list_screenshots W List screenshots for a computer
?action=upload_screenshot W Upload a screenshot (from target PC)
sse/commands.php SSE (Server-Sent Events) command stream — audit item #13, 2026-05-11. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

system_metrics.php System Metrics API X-API-Token company-scopedrole-gated
actiondescription
?action=debug R
?action=fleet_summary R
?action=get R Get latest metrics for a user
?action=history R Recent CPU/RAM samples for a user (sparklines; default 180m)
?action=list_all R List all users with their latest metrics summary
?action=submit R Submit metrics from client

public-site — 16 endpoints

customer_experience.php Customer Experience API X-API-Token (per action; ?action=public is anonymous) company-scoped
actiondescription
?action=feedback W Sunday Forms API Receives website form submissions (e.g.
?action=get R Fetch a single entry (company-scoped).
?action=list R List customer-experience entries for a company, newest first, with optional status / outcome / rating / free-text filters and pagination.
?action=set_status W Move an entry through the new → attended → closed workflow.
?action=stats R CSAT aggregates for the company over a trailing window (default 30 days).
?action=submit W Sunday Forms API Receives website form submissions (e.g.
group_before_after.php Group Before & After API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=delete W Delete a before/after item
?action=get R Get a single before/after item
?action=list R List all before/after items for a group
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for before/after items
?action=save W Create/update a before/after item
?action=upload_image W Delete a before/after item (auth required) → entityHandleDelete (shared/group_entity_crud.php) / /** Reorder before/after items (auth required) → entityHandleReorder (shared/group_entity_crud.php) / /
group_faq.php Group FAQ API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=delete W Delete a FAQ
?action=get R Get a single FAQ
?action=list R List all FAQs for a group
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for FAQs
?action=save W Create/update a FAQ
group_reviews.php Group Reviews API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=delete W Delete a review
?action=get R Get a single review
?action=list R List all reviews for a group
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for reviews
?action=save W Create/update a review
group_stores.php Group Stores API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=delete W Delete a store
?action=get R Get a single store
?action=list R List all stores for a group
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for stores
?action=save W Create/update a store
group_team.php Group Team API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=categories R Get distinct categories for a group
?action=delete W Delete a team member
?action=get R Get a single team member
?action=list R List all team members for a group
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for team members
?action=reorder_categories W Update category display order
?action=save W Create/update a team member
?action=upload_photo W Upload a team member photo (auth required).
plugin_register.php Plugin Registration Endpoint — Layer C onboarding. anonymous

Single-purpose endpoint — no ?action= dispatch.

site_city_pages.php Site City Pages API X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=convert_type W Convert a page between location_city / single_city
?action=create_page W Create a brand-new city/location page (auth required). "Bare page" model: creates a real, published WordPress page owned by the author for the requested type (that authorship is what the Cities tab an
?action=delete W Delete a city page record
?action=get W Get a single city page record
?action=list W List all saved city page records for a site
?action=public R Public endpoint (no auth) keyed by wp_page_id
?action=save W Create/update city page data (upserts on site_id+wp_page_id)
?action=wp_pages W Proxy: fetch WordPress city pages + merge saved data
site_content_blocks.php Site Content Blocks API X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=delete W Delete a content block (auth)
?action=get W Get a single content block (auth)
?action=list W List all content blocks for a site (auth)
?action=public R Public endpoint (no auth), keyed by slug
?action=save W Create/update (upserts on site_id+slug) (auth)
site_franchises.php Site Franchises API X-API-Token (per action; ?action=public is anonymous)
actiondescription
?action=delete W Delete a franchise
?action=get R Get a single franchise
?action=list R List all franchises for a site
?action=public R Public endpoint (no auth) for websites
?action=reorder W Update sort order for franchises
?action=save W Create/update a franchise
site_seo_locations.php Site SEO Locations API X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=delete W Delete an SEO location record
?action=get W Get a single SEO location record
?action=list W List all saved SEO location records for a site
?action=public R Public endpoint (no auth) keyed by wp_page_id
?action=save W Create/update SEO location data (upserts on site_id+wp_page_id)
?action=wp_pages W Proxy: fetch WordPress SEO City pages + merge saved data
site_services.php Site Services API X-API-Token (per action; ?action=public is anonymous) role-gated
actiondescription
?action=delete W Delete a service record
?action=get W Get a single service record
?action=list W List all saved service records for a site
?action=public R Public endpoint (no auth) keyed by wp_page_id
?action=reorder W Update sort order
?action=save W Create/update service data (upserts on site_id+wp_page_id)
?action=wp_pages W Proxy: fetch WordPress service pages + merge saved data
video_embed.php In-app video embed page. UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

web_chat.php api/web_chat.php — Live-chat endpoint for the A1 Tools WordPress plugin X-API-Token (per action; ?action=public is anonymous) company-scopedrole-gated
actiondescription
?action=abandon W
?action=attended W
?action=dispatcher_read W
?action=dispatcher_send W
?action=dispatcher_typing W
?action=dispatcher_upload W ── dispatcher: form submissions (uses same endpoint) ─────────
?action=form_submission_attend W
?action=form_submission_detail W
?action=list_attenders W Return the list of users eligible to be the attender of a web chat for the picker UI.
?action=list_form_submissions W
?action=list_sessions W paginated list of chat sessions for a company.
?action=mark_visitor_read W
?action=poll W Long-poll for visitor.
?action=resolve W
?action=resume R re-attach a visitor's localStorage token to its open session (called on page load to figure out whether the chat window should restore).
?action=send W
?action=session_messages W full thread for a session.
?action=set_status W Generic status setter.
?action=start W create a new chat session.
?action=transfer W Transfer chat attendance from the current owner to another user.
?action=typing W
?action=upload W
?action=visitor_left W (2026-08-13) The visitor closed the chat / left the page.
web_forms.php api/web_forms.php — Public receiver for the A1 Tools WordPress plugin X-API-Token (per action; ?action=public is anonymous) company-scoped

Single-purpose endpoint — no ?action= dispatch.

website_variables.php Website Variables API X-API-Token (per action; ?action=public is anonymous) company-scoped
actiondescription
?action=bulk_save W #146 — apply the SAME value for a few chosen fields across many sites.
?action=completeness R Bulk completeness — per-site count of MISSING required SEO fields across all sub-tabs, for the sidebar badges.
?action=get R Get variables for a specific site
?action=list R List all sites with variable status
?action=public R Public endpoint (no auth) for websites
?action=refresh_cache W Manually push a cache-invalidation ping to one site (auth required).
?action=save W Create/update variables for a site

social — 21 endpoints

crm/social/accounts.php CRM Social - Connected Account CRUD X-API-Token company-scoped
actiondescription
?action=delete W
?action=get R
?action=list R
?action=pinterest_boards W
?action=refresh_token W
?action=test W
crm/social/ai.php CRM Social — AI helpers (caption generation, content suggestions). X-API-Token company-scoped
actiondescription
?action=delete_key W
?action=generate_captions W
?action=get_keys_status R
?action=set_key W
crm/social/analytics.php CRM Social - Analytics Dashboard X-API-Token company-scoped
actiondescription
?action=account_summary R
?action=dashboard R
?action=platform_breakdown R
?action=post R
?action=top_posts R
crm/social/analytics_fetchers.php CRM Social — Per-platform analytics fetchers. UNKNOWN

Single-purpose endpoint — no ?action= dispatch.

crm/social/approvals.php CRM Social - Approval Workflow X-API-Token company-scoped
actiondescription
?action=approve W
?action=bulk_approve W
?action=bulk_schedule W
?action=history R
?action=reject W
?action=request_changes W
?action=submit_review W
crm/social/credentials.php CRM Social - Platform OAuth Credentials Management X-API-Token company-scoped
actiondescription
?action=company_delete W Delete a company's app credentials for one platform.
?action=company_get R Read a company's app credentials for every platform (secrets masked).
?action=company_save W Save a company's app credentials for one platform.
?action=company_status R CRM Social - Platform OAuth Credentials Management Developer-only.
?action=delete W
?action=get R
?action=save W
?action=test R Per-company app credentials (Spec 3) — encrypted per-company store
crm/social/cron.php CRM Social - Cron Tasks URL key / cron token company-scoped
actiondescription
?action=cleanup W
?action=fetch_analytics W
?action=publish W
?action=refresh_tokens W
crm/social/crosspost_bridge.php A1 Leads → Social crosspost mirror bridge (suggestion #102). X-API-Token company-scoped
actiondescription
?action=connections R GET ?action=connections&company_id=<id> Report connection state for all three platforms so A1 Leads' heartbeat always sees a complete picture (connected:false when the account is absent or inactive).
?action=delete_post W POST ?action=delete_post body { company_id, username, platform, post_id?|permalink? } Destructive: gated on canSocialApprove() exactly like unpublish.php's take-down.
?action=post W POST ?action=post body { company_id, ref, image_url, caption, platforms:[...] }
?action=posts W GET ?action=posts&company_id=<id>&limit=<n> Read the recent posts straight off each connected platform via the Graph APIs, so the operator sees the real wall (duplicates included) — not just what our
crm/social/index.php CRM Social - Main Router & Table Setup X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

crm/social/media.php CRM Social - Media Upload/Management X-API-Token company-scoped
actiondescription
?action=delete W
?action=list R
?action=reorder W
?action=upload W
crm/social/meta_data_deletion.php Meta (Facebook / Instagram) — Data Deletion Request Callback. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

crm/social/meta_deauthorize.php Meta (Facebook / Instagram) — Deauthorize Callback. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

crm/social/oauth.php CRM Social - OAuth Connect Flow X-API-Token (per action; ?action=public is anonymous) company-scoped
actiondescription
?action=callback W No API-token validation — comes from external redirect
?action=init W
crm/social/posts.php CRM Social - Post CRUD X-API-Token company-scoped
actiondescription
?action=apply_template W
?action=calendar R
?action=create W
?action=delete W
?action=delete_template W
?action=duplicate W
?action=get R
?action=import_csv W
?action=list R
?action=list_templates R
?action=save_as_template W
?action=update W
crm/social/publish.php CRM Social - Platform Publishing X-API-Token company-scoped
actiondescription
?action=manual W
?action=retry W
crm/social/settings.php CRM Social - Per-(company,franchise) settings X-API-Token company-scoped
actiondescription
?action=bulk_update W
?action=get R
?action=update W
crm/social/signed_request.php Shared Meta/Threads signed_request verification. HMAC signature

Single-purpose endpoint — no ?action= dispatch.

crm/social/threads_data_deletion.php Threads (Meta) — Data Deletion Request Callback. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

crm/social/threads_deauthorize.php Threads (Meta) — Deauthorize Callback. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

crm/social/unpublish.php CRM Social — Unpublish (take down already-published posts). X-API-Token company-scoped
actiondescription
?action=mark_manual W Client confirms a TikTok-manual takedown: mark our row as
?action=unpublish W
crm/social/webhooks.php CRM Social - Inbound webhook receiver. HMAC signature

Single-purpose endpoint — no ?action= dispatch.

sunday — 13 endpoints

sunday/automations.php Sunday Automations API X-API-Token
actiondescription
?action=create W Create new automation
?action=create_from_template W Create from template
?action=delete W Delete automation
?action=duplicate W Duplicate automation
?action=execute_action W Execute a recurring automation action This is called by the client-side reminder service to execute item-level actions
?action=get R Get single automation with actions/conditions
?action=list R List automations for board
?action=list_recurring R List all recurring automations across all boards (for reminder service)
?action=logs R Get automation execution logs
?action=templates W Get automation templates
?action=test W Test run automation
?action=toggle W Enable/disable automation
?action=update W Update automation
?action=update_last_triggered W Update last_triggered_at timestamp for an automation
sunday/bad_reviews_sync.php Bad-Review Workflow → Sunday mirror (suggestion #30, Rodrigo, 2026-06-10). X-API-Token company-scoped
actiondescription
?action=status R
?action=upsert_cards W
sunday/board_templates.php Sunday Board Templates API X-API-Token company-scoped
actiondescription
?action=create_board W Create board from saved template
?action=delete W Delete a template
?action=get W Get template details
?action=list W List all saved templates
?action=save W Save a board as template
?action=update W Update template metadata
sunday/boards.php Sunday Boards API X-API-Token company-scopedrole-gated
actiondescription
?action=activity_log R Get activity log for board
?action=add_column W Add column to board
?action=add_column_label W Add a new label to a status/label column (board-specific) This adds a label that only exists for this column, not to global defaults
?action=add_group W Add group to board
?action=add_group_member W Add a member to a specific group (grants group-level access)
?action=add_item_member W Add a member to a specific item (grants item-level access)
?action=add_member W
?action=add_member_by_name W #92 — add a bad-review board's ASSIGNEE (an A1 Leads display name) as a board member, so A1 Tools' Sunday "new item in your board" desktop toast reaches them when a review lands (see api/sunday/notifi
?action=all_group_members R Aggregate every group-level membership row across all groups on a board, joined with the user's display name and the owning group's title.
?action=create W Create new board
?action=create_folder W
?action=create_from_template W Create board from template
?action=create_view W Create view
?action=delete W Delete board
?action=delete_column W Delete column
?action=delete_folder W
?action=delete_group W Delete group
?action=delete_view W Delete view
?action=duplicate W Duplicate board
?action=get W Get full board with columns, groups, items
?action=get_company R lightweight board → company_id lookup.
?action=get_favorites R Get user's favorite boards with board details.
?action=get_users W Get list of users for person assignment in boards This is a lighter-weight endpoint that doesn't require admin privileges Any authenticated user can get the user list for assignment purposes
?action=group_members R Get all members assigned to a specific group
?action=item_members R Get all members assigned to a specific item
?action=list W List boards for a CRM company
?action=list_folders R
?action=members R
?action=move_board W
?action=remove_group_member W Remove a member from a group
?action=remove_item_member W Remove a member from an item
?action=remove_member W
?action=reorder_boards W
?action=reorder_columns W Reorder columns
?action=reorder_favorites W Reorder favorite boards POST: username, board_ids (JSON array of board IDs in desired order)
?action=reorder_folders W Board member operations
?action=reorder_groups W Reorder groups
?action=toggle_favorite W Toggle a board as favorite (add or remove) POST: username, board_id
?action=update W Update board
?action=update_column W Update column
?action=update_folder W
?action=update_group W Update group
?action=update_group_member_access W Update a group member's access level
?action=update_item_member_access W Update an item member's access level
?action=update_member_access W Group member operations (granular access control)
?action=update_view W Update view
?action=views R List board views
sunday/forms.php Sunday Forms API X-API-Token company-scoped
actiondescription
?action=get R Get single submission
?action=list R List form submissions
?action=mappings R List form mappings
?action=save_mapping W Create/update a form mapping
?action=submit W Submit a form (creates Sunday item)
?action=validate_config W Verify secret + CRM company/franchise IDs (used by the WP plugin's "Test Connection" button)
sunday/general_automations.php Sunday General Automations API X-API-Token
actiondescription
?action=create W Create new general automation
?action=delete W Delete general automation
?action=execute W Execute a general automation action
?action=get R Get single general automation
?action=list R List all general automations
?action=list_recurring R
?action=templates R Get general automation templates
?action=toggle W Enable/disable general automation
?action=update W Update general automation
sunday/index.php Sunday API - Main Router & Table Setup X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

sunday/item_automations.php Sunday Item Automations UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

sunday/items.php Sunday Items API X-API-Token company-scopedrole-gated
actiondescription
?action=board_updates W Get all updates (comments) across all items in a board.
?action=bulk_delete W Delete a batch of items in one round-trip.
?action=create W Create new item
?action=create_subitem W Create subitem
?action=delete W Delete item
?action=delete_subitem W Delete subitem
?action=delete_update W Delete update
?action=duplicate W Duplicate item with values
?action=edit_update W Edit update
?action=get R Get single item with values and subitems
?action=get_update_counts W Get update counts for items (total and unread) GET: item_ids (comma-separated), username Returns array of {item_id, total, unread}
?action=list W List items in board
?action=mark_updates_read W Mark updates as read for a user POST: item_id, username (marks all updates for that item as read) Or: update_ids (array), username (marks specific updates as read)
?action=move W Move item to different group
?action=move_to_board W Move item to different board
?action=post_subitem_update W Post an update (comment) on a subitem.
?action=post_update W Post update/comment
?action=reorder W Reorder items in group
?action=reply_update W Reply to update
?action=search R Search items
?action=subitem_updates W Get updates (comments) for a specific subitem.
?action=subitems R List subitems
?action=update W Update item name
?action=update_subitem W Update subitem
?action=update_value W Update single column value
?action=update_values W Update multiple column values
?action=updates W Get item updates
sunday/notifications.php Sunday Notifications API X-API-Token company-scopedrole-gated
actiondescription
?action=count W Get unread notification count
?action=delete W Delete a specific notification for a user This marks it as deleted so it won't appear in their list
?action=delete_all W Delete all notifications for a user
?action=due_dates W Get due dates for calendar integration
?action=list W Get notification list
?action=mark_all_read W Mark all notifications as read for a user
?action=mark_read W Mark a specific notification as read For mentions, this updates the sunday_mentions table For other notification types, we track read state in a separate table
sunday/recurring_cron.php Recurring Status Cron / Client Check Endpoint URL key / cron token
actiondescription
?action=client_check R
?action=reset R
sunday/settings.php Sunday Settings API X-API-Token company-scoped
actiondescription
?action=create_default_label W
?action=create_label_category W Create a new label category
?action=delete_default_label W
?action=delete_label_category W Delete a label category and all its labels
?action=delete_org_setting W Delete an org-level Sunday setting
?action=delete_setting W Delete a company-level Sunday setting row (admin-gated)
?action=get_org_settings R Get all org-level Sunday settings (by org_id)
?action=get_settings R
?action=list_default_labels R
?action=list_label_categories R Sunday Settings API Manages global Sunday settings including default status labels Only accessible by Sunday admins / require_once __DIR__ . '/index.php'; $pdo = initApi(['GET', 'POST', 'DELETE', 'OPT
?action=reorder_default_labels W Settings
?action=update_default_label W
?action=update_label_category W Update a label category
?action=update_org_setting W Upsert an org-level Sunday setting
?action=update_setting W Org-level Settings
sunday/uploads.php Sunday Uploads API X-API-Token
actiondescription
?action=delete W Delete attachment
?action=list W List attachments for update
?action=upload W Upload file(s) to an update

training — 15 endpoints

inspection_batches.php Inspection Batches API X-API-Token company-scopedrole-gated
actiondescription
?action=complete R Mark batch completed, optionally send summary email
?action=create R Create a new batch
?action=get R Get batch with unit statuses
?action=list R List active batches for a user
?action=update R Update batch metadata / add units
inspection_image.php Token-gated serving of one inspection report image (photo or signature). X-API-Token

Single-purpose endpoint — no ?action= dispatch.

inspection_report_template.php Per-tenant inspection report appearance editor. X-API-Token company-scopedrole-gated
actiondescription
?action=get R
?action=presets R
?action=preview R
?action=save R
inspection_report_view.php Customer-facing inspection report page. X-API-Token

Single-purpose endpoint — no ?action= dispatch.

inspection_reports.php Comprehensive Inspection Reports API X-API-Token company-scopedrole-gated
actiondescription
?action=create R Create new comprehensive inspection report
?action=delete R Delete report (admin)
?action=generate_pdf R
?action=get R Get single report with all details
?action=list R List user's inspection reports
?action=list_all R List all reports (admin)
?action=list_drafts R
?action=save_draft R
?action=sync_to_workiz R
?action=update R Edit a filed (non-draft) report; matrix-gated via
?action=upload_pdf R
inspection_workflow.php Inspection Workflow Handler X-API-Token company-scopedrole-gated
actiondescription
?action=get_status W Get workflow status for a report
?action=send_email W Send email notification
?action=send_sms W Send SMS notification
kb_progress.php Knowledge Base Progress API X-API-Token company-scoped
actiondescription
?action=bulk_sync W Bulk sync progress from local storage Accepts arrays of completed topics and watched videos for a single KB
?action=complete_topic W Mark a topic as completed
?action=reset W Reset user's progress for a knowledge base
?action=watch_video W Mark a video as watched
onboarding.php Hire-side New-Hire Onboarding API (code-gated, no account required) X-API-Token company-scoped
actiondescription
?action=complete W Fetch + validate an invite by typed code.
?action=contract W Fetch + validate an invite by typed code.
?action=redeem W Lightweight per-IP rate limit on code redemption so the 8-char space can't be brute-forced.
?action=save_progress W Fetch + validate an invite by typed code.
?action=save_signature W Ensure the onboarding_config table exists.
?action=upload_document W Fetch + validate an invite by typed code.
training_dashboard.php Training Dashboard API X-API-Token company-scopedrole-gated
actiondescription
?action=all_results R Get all test results
?action=all_users R Get all users' training status
?action=assign_training W Assign a training guide (kb_id) or test (test_id) to a user. $caller is the authenticated username (the manager) — the source of truth for assigned_by; a client-supplied assigned_by is ignored for att
?action=grant_attempts W Grant extra attempts to a user
?action=list_assignments W List training assignments visible to the caller.
?action=live R Get users currently taking tests
?action=reset_attempts W Reset a user's test attempts
?action=stats R Get dashboard statistics
?action=user_detail R Get detailed info for a user
training_knowledge_base.php Training Knowledge Base API X-API-Token company-scopedrole-gated
actiondescription
?action=chapters R
?action=create_chapter W
?action=create_kb W
?action=create_section W
?action=create_topic W
?action=delete_chapter W
?action=delete_kb W Chapter actions
?action=delete_section W
?action=delete_topic W
?action=get R
?action=get_for_test R
?action=list R
?action=reorder_chapters W Section actions
?action=reorder_sections W Topic actions
?action=reorder_topics W
?action=sections R
?action=test R Knowledge Base actions
?action=topic R
?action=topics R
?action=update_chapter W
?action=update_kb W
?action=update_section W
?action=update_topic W
training_progress.php Training Progress API X-API-Token company-scoped
actiondescription
?action=clear W Clear progress (abandon attempt)
?action=start W Training Progress API Handles real-time progress tracking for users taking tests Endpoints: - POST: Start test, update progress, clear progress - GET: Get current progress for a user's test / // Load
?action=update W Update progress
training_questions.php Training Questions API X-API-Token company-scoped
actiondescription
?action=bulk_create W Bulk create questions (for importing)
?action=create W Create a new question
?action=delete W Delete a question
?action=duplicate W Duplicate a question
?action=reorder W Reorder questions
?action=toggle_active W Toggle question active status
?action=update W Update a question
training_results.php Training Results API X-API-Token company-scopedrole-gated
actiondescription
?action=detail R
?action=status R
?action=submit R
training_scope_helpers.php X-API-Token company-scopedrole-gated

Single-purpose endpoint — no ?action= dispatch.

training_tests.php Training Tests API X-API-Token company-scopedrole-gated
actiondescription
?action=create W Create a new test
?action=delete W Delete a test
?action=toggle_active W Toggle test active status
?action=update W Update a test

workiz — 7 endpoints

workiz/cron_sync.php Workiz cron entry-point. URL key / cron token

Single-purpose endpoint — no ?action= dispatch.

workiz/migrations.php Workiz sync schema migrations UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

workiz/outbox_producer.php api/workiz/outbox_producer.php — Workiz outbound write producer (Phase 8.1). UNKNOWN company-scoped

Single-purpose endpoint — no ?action= dispatch.

workiz/sync_admin.php Workiz sync — admin endpoints for the integration screen. X-API-Token company-scopedrole-gated
actiondescription
?action=events R
?action=force_sync W Synchronously run a sync now.
?action=list_team_mappings R Team-mapping grid: every Workiz team member for this location, with the currently-mapped A1 username (or null = unmapped), plus the list of selectable A1 users for the dropdown.
?action=outbox_drain W Drain one batch of pending outbox rows across every location.
?action=outbox_retry_failed W
?action=outbox_status R Outbox status summary for the admin panel.
?action=reconcile R Phase 9 reconciliation report — the cutover go/no-go check.
?action=reset W
?action=set_company_mapping W
?action=set_sync_enabled W
?action=set_team_mapping W Map (or unmap) a Workiz person to an A1 user across EVERY account they appear in.
?action=set_webhook_secret W The webhook_secret column and webhook.php's HMAC gate have existed
?action=set_write_enabled W
?action=status R Workiz sync — admin endpoints for the integration screen. ───────────────────────────────────────────────────────── All actions require role ∈ {admin, developer, tester}.
workiz/sync_engine.php Workiz sync engine — shared by cron, webhook, and admin force-sync. UNKNOWN company-scoped
actiondescription
?action=job_add_payment W
?action=job_append_report_link W Workiz's public REST returns `"flag": true` (boolean) for success on most endpoints — NOT the literal string `"Success"` that the (incomplete) developer.workiz.com OpenAPI spec implies.
?action=job_assign W
?action=job_create W
?action=job_unassign W
?action=job_update W
?action=lead_activate W
?action=lead_assign W
?action=lead_convert W
?action=lead_create W
?action=lead_mark_lost W
?action=lead_unassign W
?action=lead_update W
workiz/webhook.php Workiz inbound-webhook endpoint (Phase 0 stub). HMAC signature

Single-purpose endpoint — no ?action= dispatch.

workiz_locations.php Workiz Locations API X-API-Token company-scoped
actiondescription
?action=delete_location W Delete a location
?action=get_location_status R Get location status for a user - checks if user has access to location and if it's configured
?action=list_locations R List all Workiz locations
?action=login_workiz W Login to Workiz and extract session tokens
?action=save_api_token W Save API token for a location (permanent authentication - preferred method) API tokens don't expire and work from any IP address Optionally accepts API secret for future write operations (create estim
?action=save_credentials W Save credentials extracted from WebView login
?action=save_location W Create or update a location
?action=search_jobs W Search jobs from Workiz API
?action=test_location W Test location credentials