API Reference
Every API endpoint with parameters, authentication, and response models
Base URL: https://api.maverick-ins.com/api/v1
Authentication: All endpoints require Authorization: Bearer <token> unless marked Public.
Swagger UI: https://api.maverick-ins.com/docs
Endpoint Groups
| Module | Prefix | Auth | Description |
|---|---|---|---|
| jobs | /jobs | Admin | jobs |
| contacts | /contacts | Admin | contacts |
| batches | /batches | Admin | batches |
| leads | /leads | Admin | leads |
| admin | /admin | Admin | admin |
| diagnostics | /diagnostics | Admin | Workspace Diagnostics (cause-layer scan) |
| credentials | /credentials | Admin | credentials |
| zipcodes | /zipcodes | Admin | zipcodes |
| geo | /geo | Admin | geographic |
| bison | `` | Admin | Email Bison lead/tag management |
| progress | /progress | Admin | SSE progress endpoints |
| pipeline | /pipeline | Admin | One-click pipeline execution |
| crm | `` | Admin | CRM integration management |
| gap_to_goal | /contacts/gap-to-goal | Admin | gap-to-goal |
| infrastructure_orders | `` | Admin | infrastructure-orders |
| client_onboardings | `` | Admin | client-onboardings |
| burnt_cohorts | `` | Admin | burnt-cohorts |
| onboarding | /admin | Admin | onboarding |
| agent | /agent | Admin | agent |
| status | /status | Admin | status |
| operating_intake | /ops-intake | Admin | ops-intake |
| tasks | /tasks | Auth | tasks |
| billing | `` | Admin | Cheap Inboxes billing audit |
| analytics | /analytics | Auth | analytics |
| campaigns | /campaigns | Auth | campaigns |
| revenue | /revenue | Auth | revenue |
| revenue_adjustments | /revenue | Auth | revenue-adjustments |
| client_leads | /client-leads | Auth | client-leads |
| replies | /replies | Auth | replies |
| hall_of_fame | /hall-of-fame | Auth | hall-of-fame |
| reply_templates | /reply-templates | Auth | reply-templates |
| sma_policies | /sma-policies | Auth | sma-policies |
| announcements | /announcements | Auth | Client notification system; admin endpoints enforce require_admin_or_team per-endpoint |
| resources | /resources | Auth | resources |
| resource_requests | /resource-requests | Auth | resource-requests |
| carrier_scrub | /carrier-scrub | Auth | carrier-scrub |
| audit | /audit | Auth | Insights reads; POST triggers + /health enforce require_admin per-endpoint |
| test | /test | Public | test |
| webhooks | /webhooks | Public | webhooks |
| aiark_webhook | /aiark | Public | AI-Ark bulk-export deliveries - shared-secret auth |
| slack_webhooks | /slack | Public | Slack callbacks - HMAC-signed |
| sse | `` | Public | No auth - SSE from authenticated frontend |
Jobs
Prefix: /jobs | Auth: Admin
POST /api/v1/jobs/scrape
Create a new Xpressdocs scraping job.
Response model: ScrapingJobResponse
GET /api/v1/jobs/{job_id}
Get status of a specific scraping job.
Response model: ScrapingJobResponse
GET /api/v1/jobs
List scraping jobs with optional filtering.
Response model: List
GET /api/v1/jobs/{job_id}/details
Get enhanced details for a specific scraping job.
Response model: JobDetailsResponse
GET /api/v1/jobs/{job_id}/logs
Get detailed logs for a specific job.
Response model: List
DELETE /api/v1/jobs/{job_id}
Cancel a pending or running scraping job.
GET /api/v1/jobs/stats/overview
Get overall job statistics.
DELETE /api/v1/jobs/{job_id}/permanent
Permanently delete a scraping job and its associated data.
POST /api/v1/jobs/{job_id}/restart
Restart a failed or cancelled job in-place.
Response model: ScrapingJobResponse
Contacts
Prefix: /contacts | Auth: Admin
GET /api/v1/contacts/
List contacts with filtering, search, and pagination.
Response model: ContactListResponse
GET /api/v1/contacts/stats
Get contact statistics.
Response model: ContactStats
POST /api/v1/contacts/
Create a new contact.
PUT /api/v1/contacts/{contact_id}
Update a contact.
DELETE /api/v1/contacts/{contact_id}
Delete a contact.
POST /api/v1/contacts/upload
Upload contacts via CSV file.
Response model: UploadResponse
GET /api/v1/contacts/export/csv
Export contacts as CSV.
POST /api/v1/contacts/{contact_id}/assign
Assign a contact to a different workspace.
GET /api/v1/contacts/verified
List verified contacts with filtering, search, and pagination.
Response model: ContactListResponse
GET /api/v1/contacts/verified/stats
Get verified contact statistics.
Response model: VerifiedContactStats
GET /api/v1/contacts/verified/{contact_id}
Get a single verified contact by ID.
GET /api/v1/contacts/verified/export/csv
Export verified contacts as CSV.
GET /api/v1/contacts/{contact_id}
Get a single contact by ID.
POST /api/v1/contacts/filter
Trigger contact filtering worker for a workspace.
POST /api/v1/contacts/verify
Trigger email verification worker for a workspace.
GET /api/v1/contacts/verification/bulk/jobs/latest
Get the latest bulk verification job for a workspace.
GET /api/v1/contacts/verification/bulk/jobs/{job_id}
Get status of a specific bulk verification job.
POST /api/v1/contacts/verification/resume
Resume a pending bulk verification job.
POST /api/v1/contacts/verification/reset-stuck
Reset contacts stuck in 'verifying' status back to 'ready_for_verification'.
Batches
Prefix: /batches | Auth: Admin
GET /api/v1/batches/
List weekly batches with filtering and pagination.
Response model: BatchListResponse
GET /api/v1/batches/stats
Get batch statistics.
Response model: BatchStats
GET /api/v1/batches/{batch_id}
Get batch details including associated contacts.
POST /api/v1/batches/generate
Generate monthly batch for a workspace.
POST /api/v1/batches/generate-all
Generate weekly batches for all workspaces.
POST /api/v1/batches/upload-all-pending
Atomically generate batches and upload all pending batches to Email Bison.
POST /api/v1/batches/{batch_id}/upload
Upload a batch to Email Bison.
POST /api/v1/batches/{batch_id}/retry
Retry uploading a failed batch to Email Bison.
GET /api/v1/batches/{batch_id}/download
Download batch contacts as CSV file.
DELETE /api/v1/batches/{batch_id}
Delete a batch.
DELETE /api/v1/batches/cleanup/by-month
Delete all batches for a specific month.
Response model: BatchDeleteByMonthResponse
Leads
Prefix: /leads | Auth: Admin
Endpoints defined in app/api/v1/leads.py (complex patterns, see source)
Admin
Prefix: /admin | Auth: Admin
GET /api/v1/admin/users
List all users with optional filtering.
POST /api/v1/admin/users/invite
Invite a new user to the platform.
PATCH /api/v1/admin/users/{user_id}
Update user profile.
DELETE /api/v1/admin/users/{user_id}
Deactivate a user (soft delete).
GET /api/v1/admin/workspaces
List all client workspaces.
POST /api/v1/admin/workspaces
Create a new client workspace.
POST /api/v1/admin/send-slack-report
Send a daily volume report to Slack matching Thomas's format.
POST /api/v1/admin/workspaces/generate-all-bison-tokens
Generate Email Bison API tokens for all workspaces that:
PATCH /api/v1/admin/workspaces/{workspace_name}
Update a workspace.
GET /api/v1/admin/workspaces/{workspace_name}/setup-status
Compute onboarding completion status from existing data.
POST /api/v1/admin/workspaces/{workspace_name}/generate-bison-token
Generate an Email Bison API token for a workspace.
GET /api/v1/admin/filter-rules
List filter rules.
POST /api/v1/admin/filter-rules
Create a new filter rule.
PATCH /api/v1/admin/filter-rules/{rule_id}
Update a filter rule.
DELETE /api/v1/admin/filter-rules/{rule_id}
Delete a filter rule.
GET /api/v1/admin/audit-logs
List audit log entries.
GET /api/v1/admin/settings
Get system settings.
PUT /api/v1/admin/settings
Update system settings.
Diagnostics
Prefix: /diagnostics | Auth: Admin | Workspace Diagnostics (cause-layer scan)
POST /api/v1/diagnostics/run
Dispatch an on-demand diagnostics scan (async — poll /runs for status).
GET /api/v1/diagnostics/runs
Recent scan runs, newest first.
GET /api/v1/diagnostics/findings
Forensic (per-campaign, per-run) findings. Lifecycle/dedup state lives
Credentials
Prefix: /credentials | Auth: Admin
POST /api/v1/credentials/
Create a credential without echoing supplied secret material.
Response model: CredentialResponse
GET /api/v1/credentials/
List all credentials (without passwords).
Response model: List
GET /api/v1/credentials/{credential_id}
Get a single credential by ID.
PUT /api/v1/credentials/{credential_id}
Update a credential. If password provided, updates vault secret.
Response model: CredentialResponse
DELETE /api/v1/credentials/{credential_id}
Delete a credential and its vault secret.
POST /api/v1/credentials/{credential_id}/test
Test a credential by retrieving password from vault and validating.
Response model: TestCredentialResponse
GET /api/v1/credentials/for-state/{state}
Get appropriate credential for a specific state.
GET /api/v1/credentials/coverage/map
Get coverage map of all states and their available credentials.
Response model: StateCoverageResponse
Zipcodes
Prefix: /zipcodes | Auth: Admin
GET /api/v1/zipcodes/workspaces/{workspace_name}/assigned
Fetch assigned ZIP codes for a workspace.
GET /api/v1/zipcodes/assignments
List ZIP code assignments with optional filtering.
POST /api/v1/zipcodes/assignments
Assign a ZIP code to a workspace.
POST /api/v1/zipcodes/assignments/bulk
Bulk upload ZIP assignments from CSV.
DELETE /api/v1/zipcodes/assignments/{assignment_id}
Remove a ZIP assignment.
POST /api/v1/zipcodes/assignments/seed
Seed ZIP assignments from master-list.csv format.
POST /api/v1/zipcodes/assignments/bulk-delete
Bulk delete ZIP assignments by their IDs.
DELETE /api/v1/zipcodes/assignments/bulk
Bulk delete ZIP assignments.
GET /api/v1/zipcodes/assignments/export
Export ZIP assignments as CSV or JSON.
GET /api/v1/zipcodes/assignments/coverage
Get coverage statistics for ZIP assignments.
GET /api/v1/zipcodes/zip/search
Search ZIP codes from the master us_zip_codes table.
POST /api/v1/zipcodes/assignments/bulk-add
Add multiple ZIP code assignments to a workspace.
GET /api/v1/zipcodes/workspaces/{workspace_name}/stats
Get detailed assignment statistics for a workspace.
Geo
Prefix: /geo | Auth: Admin
GET /api/v1/geo/states
List all US states with optional region filtering.
Response model: List
GET /api/v1/geo/states/{abbreviation}
Get details for a specific state by abbreviation.
Response model: StateResponse
GET /api/v1/geo/states/{abbreviation}/zips
Get ZIP codes for a specific state with pagination.
GET /api/v1/geo/zip/{zip_code}
Get details for a specific ZIP code.
Response model: ZipCodeResponse
GET /api/v1/geo/viewport
Get ZIP codes visible in a map viewport (bounding box).
GET /api/v1/geo/coverage
Get coverage statistics showing assigned vs total ZIPs per state.
POST /api/v1/geo/lookup/state
Lookup state information for multiple ZIP codes.
GET /api/v1/geo/regions
List all geographic regions with their states.
GET /api/v1/geo/public/states
Public endpoint to get all US states.
GET /api/v1/geo/public/zip/{zip_code}/state
Public endpoint to get state for a ZIP code.
POST /api/v1/geo/public/lookup/states
Public endpoint to lookup states for multiple ZIP codes.
Bison
Prefix: `` | Auth: Admin | Email Bison lead/tag management
GET /api/v1/leads
List all leads in the current workspace (paginated).
Response model: LeadListResponse
GET /api/v1/leads/search
Search leads by email address.
GET /api/v1/leads/{lead_id}
Get details for a specific lead.
Response model: LeadResponse
DELETE /api/v1/leads/{lead_id}
Delete a single lead.
Response model: DeleteResponse
POST /api/v1/leads/bulk-delete
Delete multiple leads at once.
Response model: DeleteResponse
GET /api/v1/tags
List all tags in the current workspace.
Response model: TagListResponse
POST /api/v1/tags
Create a new tag.
GET /api/v1/tags/{tag_id}/leads
Get all leads with a specific tag.
DELETE /api/v1/tags/{tag_id}
Delete a tag.
Response model: DeleteResponse
POST /api/v1/tags/attach-to-leads
Attach tags to multiple leads.
POST /api/v1/tags/detach-from-leads
Remove tags from multiple leads.
GET /api/v1/uploaded-batches
List batches that have been uploaded to Email Bison.
Response model: UploadedBatchResponse
POST /api/v1/uploaded-batches/{batch_id}/revert
Revert a batch upload by deleting all leads that were uploaded.
GET /api/v1/infrastructure/accounts
List all email accounts with their Email Bison sync data.
GET /api/v1/infrastructure/accounts/unhealthy
List individual unhealthy email accounts for a workspace.
PATCH /api/v1/accounts/{account_id}/pause
Pause an email account in Email Bison.
PATCH /api/v1/accounts/{account_id}/resume
Resume a paused email account in Email Bison.
GET /api/v1/infrastructure/accounts/{email_or_id}/trend
Return a per-day series (last N days) + rolling-window totals for a mailbox.
GET /api/v1/infrastructure/activity
Get infrastructure-relevant webhook activity.
GET /api/v1/infrastructure/launch-schedule
Launch schedule sorted by nearest launch date, from two sources:
GET /api/v1/infrastructure/action-items/{workspace_name_param}/download
Download CSV of problematic accounts for a specific client and issue type.
GET /api/v1/infrastructure/burnt-domains
Get domain-level health report for burnt domain detection.
GET /api/v1/infrastructure/burnt-domains/download
Download a CSV of all accounts belonging to burnt domains, with full per-account stats.
POST /api/v1/sync-now
Trigger a full Bison sync + stats cache rebuild from the dashboard.
POST /api/v1/infrastructure/tag-burnt-accounts
Tag the April-28 CIM burnt cohort with the "Burnt" tag in Email Bison.
POST /api/v1/infrastructure/quarantine-burnt-accounts
Tag the burnt cohort "Burnt", then remove them from all campaigns.
GET /api/v1/cache-status
Get the last sync timestamp for the workspace stats cache.
POST /api/v1/sync
Manually trigger Email Bison data sync.
Response model: SyncResponse
GET /api/v1/sync/status/{task_id}
Get status of a background sync task.
GET /api/v1/sync/last
Get information about the last sync for a workspace.
PATCH /api/v1/campaigns/{campaign_id}/pause
Pause an active Email Bison campaign.
PATCH /api/v1/campaigns/{campaign_id}/resume
Resume a paused Email Bison campaign.
POST /api/v1/campaigns/{campaign_id}/duplicate
Duplicate an Email Bison campaign (creates a draft copy).
GET /api/v1/workspace-stats
Get workspace-level sending KPIs.
GET /api/v1/workspace-chart
Get workspace time-series chart data (sent, replied, interested, bounced).
GET /api/v1/all-workspaces-stats
Get aggregated stats across all active workspaces.
GET /api/v1/all-workspaces-chart
Get aggregated time-series chart data across all active workspaces.
GET /api/v1/wow-chart
Get daily WoW comparison data for charting.
GET /api/v1/replies/live-stats
Get live reply stats combining Bison counts with local response time data.
GET /api/v1/replies
List replies across workspace with search and filtering, enriched with local data.
GET /api/v1/campaigns/{campaign_id}/replies
Get replies for a specific campaign, enriched with local sentiment data.
PATCH /api/v1/replies/{reply_id}/interested
Toggle interested status on a reply.
GET /api/v1/replies/{reply_id}
Get a single reply by ID from Email Bison.
POST /api/v1/replies/{reply_id}/reply
Send a reply to an existing message through Email Bison.
POST /api/v1/replies/{reply_id}/forward
Forward a reply message to another email address.
GET /api/v1/replies/{reply_id}/thread
Get the full conversation thread for a reply.
PATCH /api/v1/replies/{reply_id}/read
Toggle read/unread status on a reply.
PATCH /api/v1/replies/{reply_id}/not-interested
Mark a reply as not interested.
PATCH /api/v1/replies/{reply_id}/automated
Toggle automated/not-automated flag on a reply.
POST /api/v1/replies/{reply_id}/followup
Push a replied lead into a follow-up campaign.
POST /api/v1/replies/{reply_id}/unsubscribe
Unsubscribe a lead from the reply context.
PATCH /api/v1/replies/{reply_id}/mark-handled
Mark a reply as handled by stamping our_reply_sent_at in lead_replies.
PATCH /api/v1/replies/{reply_id}/unmark-handled
Remove handled status from a reply by clearing our_reply_sent_at.
POST /api/v1/replies/bulk-action
Perform bulk actions on multiple replies.
GET /api/v1/bounces
Aggregate bounced emails with their bounce messages across campaigns.
GET /api/v1/campaigns/{campaign_id}/scheduled-emails
Get pending/scheduled emails for a campaign (Bison page 1 + meta).
GET /api/v1/campaigns/{campaign_id}/sender-emails
Get ALL sender email accounts attached to a campaign.
GET /api/v1/campaigns/{campaign_id}/chart-stats
Get time-series chart data for a specific campaign. Cached for 1 hour.
POST /api/v1/replies/{reply_id}/generate-draft
Generate an AI-powered draft reply for a Bison reply.
GET /api/v1/auto-reply/config
Get auto-reply configuration for a workspace.
POST /api/v1/auto-reply/config
Create or update auto-reply configuration for a workspace.
PATCH /api/v1/auto-reply/config/toggle
Quick toggle to enable/disable auto-reply for a workspace.
GET /api/v1/auto-reply/log
View auto-reply history with pagination.
POST /api/v1/auto-reply/test
Dry-run: classify sentiment and generate a reply for a specific Bison reply WITHOUT sending.
GET /api/v1/daily-stats-summary
Aggregate daily sending stats from workspace_daily_stats for the overview page.
GET /api/v1/infrastructure/live-disconnects
Live-fetch disconnected ('Not connected') sender accounts directly from Bison
GET /api/v1/infrastructure/live-disconnects/download
CSV download of the live-disconnects snapshot. Same data as /live-disconnects.
Progress
Prefix: /progress | Auth: Admin | SSE progress endpoints
GET /api/v1/progress/filtering/{task_id}
SSE endpoint for filtering task progress.
GET /api/v1/progress/verification/{task_id}
SSE endpoint for verification task progress.
GET /api/v1/progress/filtering/{task_id}/status
Get current filtering task status (non-streaming).
Response model: FilteringTaskProgress
GET /api/v1/progress/verification/{task_id}/status
Get current verification task status (non-streaming).
Response model: VerificationTaskProgress
Pipeline
Prefix: /pipeline | Auth: Admin | One-click pipeline execution
POST /api/v1/pipeline/execute
Execute complete pipeline with one click.
Response model: PipelineResponse
GET /api/v1/pipeline/{run_id}/status
Get detailed pipeline execution status.
Response model: PipelineStatusResponse
POST /api/v1/pipeline/{workspace_name}/from-stage
Execute pipeline starting from a specific stage.
Response model: PipelineResponse
GET /api/v1/pipeline/
List recent pipeline runs.
Response model: List
POST /api/v1/pipeline/{run_id}/cancel
Cancel a running pipeline.
POST /api/v1/pipeline/{run_id}/retry
Retry a failed pipeline from its failed stage.
POST /api/v1/pipeline/process-all
Sequentially drain pending contacts for every active workspace.
POST /api/v1/pipeline/upload-all
Upload all verified contacts that are pending upload.
Crm
Prefix: `` | Auth: Admin | CRM integration management
GET /api/v1/configs
List workspaces with their CRM destinations.
Response model: List
GET /api/v1/configs/{workspace_name}
Return one workspace's CRM config bundle.
Response model: WorkspaceCRMResponse
PUT /api/v1/configs/{workspace_name}
DEPRECATED. Use POST /destinations, PATCH /destinations/{id}, DELETE /destinations/{id}.
POST /api/v1/destinations
Create a new CRM destination. One workspace can have many.
Response model: DestinationResponse
PATCH /api/v1/destinations/{destination_id}
Update fields on an existing destination. Only provided fields change.
Response model: DestinationResponse
DELETE /api/v1/destinations/{destination_id}
Soft-delete (is_active=false). Historical delivery log rows keep their
POST /api/v1/destinations/{destination_id}/test
Send a synthetic ping to one destination. Uses OPTIONS/HEAD/no-op style
Response model: CRMTestResponse
GET /api/v1/delivery-logs
Recent CRM delivery attempts. Supports per-destination filtering.
Response model: List
GET /api/v1/health
Aggregate health: workspace counts, last-24h delivery success rate,
Response model: Dict
POST /api/v1/retry-failed
Queue failed deliveries for retry via dispatch_by_log. Excludes rows
Gap To Goal
Prefix: /contacts/gap-to-goal | Auth: Admin
POST /api/v1/contacts/gap-to-goal/fill
Fill contact gap from the master database.
Response model: GapToGoalFillResponse
GET /api/v1/contacts/gap-to-goal/availability
Check master database availability for a workspace.
Response model: AvailabilityResponse
GET /api/v1/contacts/gap-to-goal/zip-stats
Get ZIP code availability statistics from the master database.
Response model: List
GET /api/v1/contacts/gap-to-goal/pipeline-rates
Get historical pipeline attrition rates.
Response model: PipelineRatesResponse
GET /api/v1/contacts/gap-to-goal/calculate-pull
Calculate recommended pull count accounting for pipeline attrition.
Response model: PullCountCalculationResponse
GET /api/v1/contacts/gap-to-goal/state-overview
Get all states with workspace gaps for batch fill UI.
Response model: StateOverviewResponse
GET /api/v1/contacts/gap-to-goal/health
Check master database health and connectivity.
Response model: MasterDbHealthResponse
POST /api/v1/contacts/gap-to-goal/fill-batch
Launch batch fill across multiple states. Returns batch_id for progress tracking.
Response model: BatchFillResponse
GET /api/v1/contacts/gap-to-goal/batch-progress/{batch_id}
Poll batch fill progress from Redis.
Response model: BatchProgressResponse
POST /api/v1/contacts/gap-to-goal/batch-cancel/{batch_id}/{state}
Cancel a specific state's batch fill task.
Infrastructure Orders
Prefix: `` | Auth: Admin
POST /api/v1/infrastructure-orders
GET /api/v1/infrastructure-orders
GET /api/v1/infrastructure-orders/summary
GET /api/v1/infrastructure-orders/untagged-accounts
POST /api/v1/infrastructure-orders/import-from-bison
GET /api/v1/infrastructure-orders/proposals
Open reconciler proposals + the live unlinked-warming gap.
GET /api/v1/infrastructure-orders/gap-summary
Live gap counters for the page-header widget (temporary feature).
GET /api/v1/infrastructure-orders/reconciliation-runs
Recent reconciler runs (newest first) for the Reconciliation tab's
GET /api/v1/infrastructure-orders/workspace-daily
Per-workspace daily infra snapshots (infra_workspace_daily, mig 153)
Response model: WorkspaceDailyResponse
GET /api/v1/infrastructure-orders/deletion-queue
Paged queue rows + the per-workspace pending rollup (the digest's
POST /api/v1/infrastructure-orders/deletion-queue
Manually queue accounts for deletion (admin). Validates the accounts
POST /api/v1/infrastructure-orders/deletion-queue/resolve
Mark queue rows Deleted/Skip after the team worked them by hand —
POST /api/v1/infrastructure-orders/confirm-adoptions
Batch confirm (the backlog session) — per-id failure-isolated.
POST /api/v1/infrastructure-orders/confirm-adoptions-merged
Confirm selected cohorts as ONE order (one order per client per
GET /api/v1/infrastructure-orders/reseller-configs
POST /api/v1/infrastructure-orders/reseller-configs
PATCH /api/v1/infrastructure-orders/reseller-configs/{config_id}
Edit numbers/tags/display/is_active. There is deliberately NO delete
GET /api/v1/infrastructure-orders/volume-forecast
30-day tier-1 available-volume projection (capacity-forecast-v1):
GET /api/v1/infrastructure-orders/client-account-breakdown
Per-client account breakdown for the capacity tab's expandable cards:
GET /api/v1/infrastructure-orders/{order_id}
GET /api/v1/infrastructure-orders/{order_id}/account-summary
Account evidence behind one Review card (Tommy 2026-07-18, the
Response model: AccountSummaryResponse
PATCH /api/v1/infrastructure-orders/{order_id}/stage
PATCH /api/v1/infrastructure-orders/{order_id}/link-accounts
DELETE /api/v1/infrastructure-orders/{order_id}
Cancel (never hard-delete) — the row and its event history survive.
POST /api/v1/infrastructure-orders/{order_id}/confirm-adoption
Confirm a reconciler proposal: clear needs_review + apply overrides.
POST /api/v1/infrastructure-orders/{order_id}/reject-adoption
Reject a proposal: un-stamp its accounts (or re-stamp onto
POST /api/v1/infrastructure-orders/{order_id}/check-fulfillment
POST /api/v1/infrastructure-orders/{order_id}/verify-warmup
PATCH /api/v1/infrastructure-orders/{order_id}
Client Onboardings
Prefix: `` | Auth: Admin
POST /api/v1/client-onboardings
Submit a new onboarding form (new client or upgrade of existing client).
Response model: CreateOnboardingResponse
GET /api/v1/client-onboardings/search-clients
Autocomplete for the New Client form's display-name field.
GET /api/v1/client-onboardings
List client onboardings for the /onboarding pipeline board.
Response model: PipelineListResponse
PATCH /api/v1/client-onboardings/sub-orders/{sub_order_id}/domains-purchased
Hassan clicks [Domains Purchased] on a sub-order card.
PATCH /api/v1/client-onboardings/sub-orders/{sub_order_id}/order-submitted
Hassan clicks [Order Submitted].
PATCH /api/v1/client-onboardings/sub-orders/{sub_order_id}/move-confirmed
Hassan clicks [Move Confirmed] and picks the destination workspace.
GET /api/v1/client-onboardings/workspaces
Return active client_registry workspaces with a bison_workspace_id set —
Response model: List
POST /api/v1/client-onboardings/link-workspace
Link a Bison workspace that was created directly in Bison (not through
Response model: LinkWorkspaceResponse
GET /api/v1/client-onboardings/search-bison-workspaces
Search Bison workspaces by name for the Link Workspace modal.
Response model: List
PATCH /api/v1/client-onboardings/{onboarding_id}/set-domains-and-workspace
[Set domains & workspace] on the client card. Enables the auto-detector.
DELETE /api/v1/client-onboardings/{onboarding_id}
Cancel a client onboarding. Sub-orders are cancelled through the stage
POST /api/v1/client-onboardings/{onboarding_id}/launch
[Ready to Launch] button — full auto-launch.
Burnt Cohorts
Prefix: `` | Auth: Admin
GET /api/v1
Response model: WeekBlockList
GET /api/v1/{cohort_id}
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/confirm
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/split-and-wind-down
Response model: SplitResponse
POST /api/v1/{cohort_id}/confirm-and-wind-down
Response model: ConfirmAndWindDownResponse
POST /api/v1/{cohort_id}/replacement-ordered
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/replacement-declined
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/reseller-cancel/request
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/reseller-cancel/confirm
Response model: BurntCohortRow
POST /api/v1/{cohort_id}/send-to-deletion-queue
Response model: SendToDeletionResponse
PATCH /api/v1/{cohort_id}/delete-after
Response model: BurntCohortRow
POST /api/v1/scan-now
Trigger a burnt-cohort scan immediately. Same code path as the
Response model: ScanNowResponse
GET /api/v1/scan-status/{task_id}
Poll the state of a scan task. UI hits this every few seconds
Response model: ScanStatusResponse
POST /api/v1/weeks/{scan_week}/dismiss
Response model: DismissResponse
Onboarding
Prefix: /admin | Auth: Admin
POST /api/v1/admin/drafts
Create a new onboarding draft.
GET /api/v1/admin/drafts
List in-progress drafts for the current user.
GET /api/v1/admin/drafts/{draft_id}
Get a specific draft by ID.
PATCH /api/v1/admin/drafts/{draft_id}
Update a draft's wizard state (auto-save on step transitions).
DELETE /api/v1/admin/drafts/{draft_id}
Delete/abandon a draft.
POST /api/v1/admin/validate-workspace-name
Check if a workspace name is available.
GET /api/v1/admin/bison-workspaces
Fetch available Bison workspaces via master API key.
POST /api/v1/admin/test-slack-webhook
Send a test message to a Slack webhook URL.
POST /api/v1/admin/parse-zip-csv
Validate parsed ZIP code rows and derive missing states.
POST /api/v1/admin/drafts/{draft_id}/complete
Orchestrator: create all resources from a completed draft.
Agent
Prefix: /agent | Auth: Admin
POST /api/v1/agent/chat
Stream an agent response.
GET /api/v1/agent/models
List available models for the agent.
GET /api/v1/agent/threads
POST /api/v1/agent/threads
GET /api/v1/agent/threads/{thread_id}
DELETE /api/v1/agent/threads/{thread_id}
Status
Prefix: /status | Auth: Admin
GET /api/v1/status/overview
Get health overview of all 8 system modules.
GET /api/v1/status/metrics/{module}
Get time-series metrics for a specific module.
GET /api/v1/status/celery
Get live Celery task detail: active tasks, queue depths, recent failures, beat schedule.
GET /api/v1/status/data-freshness
Freshness of each periodic task: last-success age vs expected interval.
GET /api/v1/status/logs/{service}
Get recent logs from a Docker container.
Operating Intake
Prefix: /ops-intake | Auth: Admin
GET /api/v1/ops-intake/source-accounts
PATCH /api/v1/ops-intake/source-accounts/{account_id}
POST /api/v1/ops-intake/google/workspace/sync-users
Queue Google Workspace user inventory sync.
POST /api/v1/ops-intake/source-accounts/{account_id}/backfill
POST /api/v1/ops-intake/source-accounts/{account_id}/sync-now
GET /api/v1/ops-intake/slack/conversations
PATCH /api/v1/ops-intake/slack/conversations/{channel_id}
POST /api/v1/ops-intake/slack/conversations/{channel_id}/backfill
POST /api/v1/ops-intake/slack/conversations/{channel_id}/sweep
GET /api/v1/ops-intake/slack/policies
POST /api/v1/ops-intake/slack/policies
GET /api/v1/ops-intake/slack/coverage
GET /api/v1/ops-intake/slack/intake-items
PATCH /api/v1/ops-intake/slack/intake-items/{item_id}
GET /api/v1/ops-intake/slack/brain-writebacks
POST /api/v1/ops-intake/slack/discover
POST /api/v1/ops-intake/slack/audit
POST /api/v1/ops-intake/index/operating-threads/{thread_id}
POST /api/v1/ops-intake/index/slack-thread
POST /api/v1/ops-intake/index/slack-backfill
POST /api/v1/ops-intake/index/operating-threads-backfill
POST /api/v1/ops-intake/promotion/slack-backfill
POST /api/v1/ops-intake/promotion/operating-threads-backfill
GET /api/v1/ops-intake/promotion/timeline-events
GET /api/v1/ops-intake/promotion/brain-patch-candidates
GET /api/v1/ops-intake/promotion/runs
GET /api/v1/ops-intake/promotion/event-links
GET /api/v1/ops-intake/promotion/aliases
GET /api/v1/ops-intake/promotion/taxonomy
PATCH /api/v1/ops-intake/promotion/brain-patch-candidates/{patch_id}
POST /api/v1/ops-intake/promotion/aliases/seed-client-registry
POST /api/v1/ops-intake/promotion/timeline-events/promote
I8: calibrated auto-promotion of client-attributed timeline events.
POST /api/v1/ops-intake/queue-maintenance/sweep
I8: weekly queue maintenance (dry_run returns counts+samples synchronously).
GET /api/v1/ops-intake/promotion/status
I8: open candidates, recent runs (incl. skip surfacing), stuck/review counts.
POST /api/v1/ops-intake/backfill/seed
Materialize the checkpointed backfill work lists (anti-joined against
GET /api/v1/ops-intake/backfill/status
Progress by job: pending/succeeded/failed/excluded/total + pct + ETA.
GET /api/v1/ops-intake/review-items
PATCH /api/v1/ops-intake/review-items/{review_item_id}
POST /api/v1/ops-intake/review-items/{review_item_id}/writebacks
Tasks
Prefix: /tasks | Auth: Auth
GET /api/v1/tasks/stats
Get task statistics for dashboard cards.
Response model: TaskStatsResponse
GET /api/v1/tasks/assignees
Get list of users assignable to tasks. FastAPI coerces dict rows
Response model: List
GET /api/v1/tasks
List tasks with optional filtering.
Response model: TaskListResponse
POST /api/v1/tasks
Create a new task. Returns ETag: <version> header.
Response model: TaskResponse
GET /api/v1/tasks/{task_id}
Get a single task by ID. Sets ETag: <version> header.
Response model: TaskResponse
GET /api/v1/tasks/{task_id}/activity
Get activity log for a task.
Response model: List
GET /api/v1/tasks/{task_id}/timeline
Full timeline for a task — system events + comments, newest first.
Response model: List
POST /api/v1/tasks/{task_id}/comments
Add a comment to a task.
Response model: TimelineEntryResponse
PATCH /api/v1/tasks/{task_id}/comments/{comment_id}
Edit a comment. Author-only.
Response model: TimelineEntryResponse
DELETE /api/v1/tasks/{task_id}/comments/{comment_id}
Soft-delete a comment. Author-only.
POST /api/v1/tasks/{task_id}/repost-slack
Fire the task.created Slack post for a task that wasn't posted at create time.
PATCH /api/v1/tasks/{task_id}
Update an existing task with optimistic concurrency control.
Response model: TaskResponse
DELETE /api/v1/tasks/{task_id}
Delete a task.
Billing
Prefix: `` | Auth: Admin | Cheap Inboxes billing audit
GET /api/v1/summary
Top-line KPIs for the /infrastructure/billing page header.
Response model: BillingSummaryOut
GET /api/v1/subscriptions
List billing subscriptions (synced from Thomas master sheet).
Response model: List
GET /api/v1/receipts
List ingested receipts. Sorted by paid_at desc.
Response model: List
GET /api/v1/disputes
List billing disputes (duplicates, off-rate, etc).
Response model: List
PATCH /api/v1/disputes/{dispute_id}
Resolve / progress a dispute (e.g. mark 'contacted_reseller' or 'refunded').
PATCH /api/v1/receipts/{receipt_number}/reassign
Operator override: bind a receipt to a specific subscription (or
POST /api/v1/audit/trigger
Force-trigger the daily billing audit (normally runs 06:00 CST).
GET /api/v1/per-client
Per-client billed-vs-expected for the period. Drives the per-client view in the UI.
Analytics
Prefix: /analytics | Auth: Auth
GET /api/v1/analytics/kpis
Get key performance indicators with REAL DATA.
Response model: KPIMetrics
GET /api/v1/analytics/time-series
Get time-series data for metrics.
GET /api/v1/analytics/contact-growth
Get contact growth metrics.
Response model: ContactGrowthMetrics
GET /api/v1/analytics/campaign-performance
Get campaign performance metrics with REAL DATA from campaign_metrics table.
GET /api/v1/analytics/workspace-comparison
Compare performance across all workspaces.
GET /api/v1/analytics/workspace-step-breakdown
Per-step engagement breakdown for one workspace, aggregated across all
GET /api/v1/analytics/funnel
Get contact pipeline conversion funnel.
GET /api/v1/analytics/cost-analysis
Get cost analysis for verification and email sending.
GET /api/v1/analytics/debounce-usage
Get Debounce email verification usage statistics.
Response model: DebounceUsageStats
GET /api/v1/analytics/activity-feed
Get activity feed for the dashboard.
Response model: ActivityFeedResponse
GET /api/v1/analytics/client-pipeline-stats
Get pipeline statistics per client/workspace for the overview dashboard.
Response model: ClientPipelineResponse
GET /api/v1/analytics/activity-feed/summary
Get activity summary with counts by event type.
GET /api/v1/analytics/client-kpi-overview
Get comprehensive KPI overview for all clients.
GET /api/v1/analytics/comparisons
Get WoW (week-over-week) or MoM (month-over-month) metric comparisons.
Response model: ComparisonResponse
GET /api/v1/analytics/time-range
Get aggregated metrics for a specific time range.
Response model: TimeRangeResponse
GET /api/v1/analytics/client-metrics
Retrieve client_metrics rows. Reads pre-computed daily snapshots
GET /api/v1/analytics/kpi-overview
Get KPI overview for a workspace. Returns the most recent
Response model: ClientMetricsKPI
GET /api/v1/analytics/roi-overview
Per-workspace ROI overview.
Response model: List
POST /api/v1/analytics/sync-metrics
Manually trigger the daily_metrics.generate_daily_client_metrics Celery
GET /api/v1/analytics/data-freshness
Returns when client_metrics was last refreshed for today's rows.
Response model: DataFreshnessResponse
GET /api/v1/analytics/daily-recap
Per-workspace breakdown for a single calendar day, split into Per-Lead
Response model: DailyRecapResponse
GET /api/v1/analytics/daily-reply-trend
Daily aggregation of replies + interested leads over the last N days
Response model: DailyReplyTrendResponse
GET /api/v1/analytics/infrastructure-alerts
Workspaces whose reply rate today dropped below threshold % (default
Response model: InfrastructureAlertsResponse
POST /api/v1/analytics/send-to-slack
Post today's KPI snapshot to the configured Slack ops channel.
Response model: SendSlackResponse
POST /api/v1/analytics/send-tomorrow-to-slack
Post tomorrow's scheduled-sending-volume snapshot to the Slack ops channel.
Response model: SendSlackResponse
Campaigns
Prefix: /campaigns | Auth: Auth
GET /api/v1/campaigns/
List campaigns with filtering and pagination.
Response model: CampaignListResponse
GET /api/v1/campaigns/{batch_id}
Get campaign details by batch ID.
PATCH /api/v1/campaigns/{batch_id}
Update campaign details.
POST /api/v1/campaigns/{batch_id}/launch
Launch a campaign by uploading to Email Bison.
POST /api/v1/campaigns/{batch_id}/pause
Pause an active campaign in Email Bison.
GET /api/v1/campaigns/{batch_id}/stats
Get campaign performance statistics from Email Bison.
Response model: CampaignStats
GET /api/v1/campaigns/{batch_id}/export/csv
Export campaign contacts and results as CSV.
GET /api/v1/campaigns/bison/list-all
List active Email Bison campaigns across the caller's workspaces.
GET /api/v1/campaigns/bison/list
List all Email Bison campaigns for a specific workspace.
POST /api/v1/campaigns/{batch_id}/assign-to-bison-campaign
Assign a batch's leads to an Email Bison campaign.
Revenue
Prefix: /revenue | Auth: Auth
GET /api/v1/revenue/breakdown
Per-client revenue, costs, profit, and margins for a given month.
Response model: RevenueBreakdownResponse
GET /api/v1/revenue/totals
Aggregate revenue, cost, and profit totals across all clients.
Response model: RevenueTotalsResponse
GET /api/v1/revenue/forecast
Revenue projections for the month.
Response model: RevenueForecastResponse
GET /api/v1/revenue/historical
Month-over-month revenue comparison.
Response model: List
GET /api/v1/revenue/daily
Daily revenue breakdown for a given month.
Response model: DailyRevenueResponse
GET /api/v1/revenue/live
Real-time revenue and lead count for a single date.
Response model: LiveDailyResponse
POST /api/v1/revenue/snapshot
Persist the current revenue state as a snapshot.
Response model: SnapshotResponse
Revenue Adjustments
Prefix: /revenue | Auth: Auth
GET /api/v1/revenue/refunds
List refunds, optionally filtered by workspace and/or month.
Response model: List
POST /api/v1/revenue/refunds
Create a refund entry. Captures price snapshot if amount not overridden.
Response model: RefundResponse
PATCH /api/v1/revenue/refunds/{refund_id}
Update mutable fields on a refund.
Response model: RefundResponse
DELETE /api/v1/revenue/refunds/{refund_id}
Delete a refund entry.
GET /api/v1/revenue/referrals
List referral credits, optionally filtered by workspace and/or month.
Response model: List
POST /api/v1/revenue/referrals
Create a referral credit entry. Defaults to $500.
Response model: ReferralResponse
PATCH /api/v1/revenue/referrals/{referral_id}
Update mutable fields on a referral credit.
Response model: ReferralResponse
DELETE /api/v1/revenue/referrals/{referral_id}
Delete a referral credit entry.
Client Leads
Prefix: /client-leads | Auth: Auth
GET /api/v1/client-leads
List leads for a workspace with optional search, filtering, and pagination.
Response model: LeadListResponse
POST /api/v1/client-leads
Create a new lead manually.
GET /api/v1/client-leads/stats
Get pipeline stage counts and summary statistics for a workspace.
Response model: PipelineStatsResponse
GET /api/v1/client-leads/{lead_id}
Get full details for a single lead.
Response model: LeadDetailResponse
PATCH /api/v1/client-leads/{lead_id}/stage
Update the pipeline stage for a lead.
Response model: UpdateLeadResponse
PATCH /api/v1/client-leads/{lead_id}/notes
Update the notes for a lead.
Response model: UpdateLeadResponse
PATCH /api/v1/client-leads/{lead_id}/assign
Assign or unassign a lead to a team member.
GET /api/v1/client-leads/{lead_id}/activity
Get the activity timeline for a lead, including all email replies.
Response model: LeadActivityResponse
Replies
Prefix: /replies | Auth: Auth
GET /api/v1/replies
List replies with filtering and pagination.
Response model: ReplyListResponse
GET /api/v1/replies/stats
Get reply statistics scoped to a recent time window (default 72h).
Response model: ReplyStatsResponse
GET /api/v1/replies/auto-forward-config
Get the auto-forward-dropped-producers config for a workspace.
Response model: AutoForwardConfigResponse
PUT /api/v1/replies/auto-forward-config
Upsert the auto-forward-dropped-producers config for a workspace.
Response model: AutoForwardConfigResponse
GET /api/v1/replies/{reply_id}/forwards
List auto_forward_log rows for a given lead_replies.id, newest first.
GET /api/v1/replies/campaign/{campaign_id}
Get replies for a specific campaign within a workspace via Email Bison.
GET /api/v1/replies/sent-history
List sent reply history from the sent_replies archive.
Response model: SentRepliesListResponse
GET /api/v1/replies/{reply_id}
Get detailed information for a single reply by ID.
Response model: ReplyDetailResponse
POST /api/v1/replies/generate
Unified AI reply generation endpoint (backend-enriched).
Response model: GenerateReplyResponse
POST /api/v1/replies/send
Send a reply or mark it as handled.
Response model: SendReplyResponse
PATCH /api/v1/replies/{reply_id}/sentiment
Manually update the sentiment and interest classification for a reply.
Response model: UpdateSentimentResponse
POST /api/v1/replies/classify-batch
Run rule-based sentiment classification on unclassified replies.
POST /api/v1/replies/sync-interested
Sync is_interested flag from Bison API to local lead_replies.
PATCH /api/v1/replies/{reply_id}/interested
Toggle interested status on a reply via Email Bison.
Hall Of Fame
Prefix: /hall-of-fame | Auth: Auth
GET /api/v1/hall-of-fame
List Hall of Fame nominations ranked by vote count.
POST /api/v1/hall-of-fame/nominate
Manually nominate a reply for the Hall of Fame.
POST /api/v1/hall-of-fame/{nomination_id}/vote
Toggle vote on a nomination. Vote if not voted, un-vote if already voted.
DELETE /api/v1/hall-of-fame/{nomination_id}
Remove a nomination (admin only). Cascade-deletes votes.
GET /api/v1/hall-of-fame/stats
Get Hall of Fame summary stats.
POST /api/v1/hall-of-fame/backfill
Trigger retroactive tone classification of existing replies (admin only).
Reply Templates
Prefix: /reply-templates | Auth: Auth
GET /api/v1/reply-templates
Get the reply template for a workspace.
Response model: TemplateResponse
PUT /api/v1/reply-templates
Create or update a reply template for a workspace.
Response model: TemplateResponse
Sma Policies
Prefix: /sma-policies | Auth: Auth
GET /api/v1/sma-policies
List SMA policies, optionally filtered by workspace.
GET /api/v1/sma-policies/summary
Get aggregated SMA commission summary for a workspace.
GET /api/v1/sma-policies/{policy_id}
Get a single SMA policy by ID.
POST /api/v1/sma-policies
Create a new SMA policy.
PATCH /api/v1/sma-policies/{policy_id}
Update an existing SMA policy.
DELETE /api/v1/sma-policies/{policy_id}
Delete an SMA policy.
Announcements
Prefix: /announcements | Auth: Auth | Client notification system; admin endpoints enforce require_admin_or_team per-endpoint
GET /api/v1/announcements/admin
Response model: ListResponse
GET /api/v1/announcements/pipeline
Automated-pipeline mission control: enrolled workspaces with their
Response model: ListResponse
POST /api/v1/announcements/pipeline/enroll
POST /api/v1/announcements/pipeline/unenroll
GET /api/v1/announcements/audience-presets
Response model: ListResponse
POST /api/v1/announcements/audience-presets
Response model: ItemResponse
PUT /api/v1/announcements/audience-presets/{preset_id}
Response model: ItemResponse
DELETE /api/v1/announcements/audience-presets/{preset_id}
GET /api/v1/announcements/email-recipients
Recipients panel: per-workspace emails with persistent toggle state,
Response model: ListResponse
POST /api/v1/announcements/email-recipients/toggle
POST /api/v1/announcements
Response model: ItemResponse
PUT /api/v1/announcements/{announcement_id}
Response model: ItemResponse
DELETE /api/v1/announcements/{announcement_id}
GET /api/v1/announcements/{announcement_id}/preview
Rendered Slack payload + resolved audience — powers the composer preview.
Response model: ItemResponse
POST /api/v1/announcements/{announcement_id}/send
Fire the fan-out. dry_run resolves audience + builds messages, sends nothing.
Response model: ItemResponse
POST /api/v1/announcements/{announcement_id}/test-send
Send to ONE workspace regardless of stored audience (still allowlist-gated).
Response model: ItemResponse
GET /api/v1/announcements/{announcement_id}/deliveries
Response model: ListResponse
GET /api/v1/announcements
Portal feed for one workspace. Global admins resolve to all active workspaces.
Response model: ListResponse
POST /api/v1/announcements/{announcement_id}/read
Resources
Prefix: /resources | Auth: Auth
GET /api/v1/resources
Response model: ListResponse
GET /api/v1/resources/categories
Response model: CategoriesResponse
GET /api/v1/resources/admin
Admin/team-only listing that includes unpublished rows.
Response model: ListResponse
GET /api/v1/resources/{resource_id}
Response model: ItemResponse
POST /api/v1/resources
Response model: ItemResponse
PUT /api/v1/resources/{resource_id}
Response model: ItemResponse
DELETE /api/v1/resources/{resource_id}
POST /api/v1/resources/upload/pdf
Response model: UploadResponse
POST /api/v1/resources/upload/thumbnail
Response model: UploadResponse
Resource Requests
Prefix: /resource-requests | Auth: Auth
POST /api/v1/resource-requests
Response model: ItemResponse
GET /api/v1/resource-requests
Response model: ListResponse
PATCH /api/v1/resource-requests/{request_id}
Response model: ItemResponse
Carrier Scrub
Prefix: /carrier-scrub | Auth: Auth
GET /api/v1/carrier-scrub/clients
Scrub-enabled clients merged with their current run status.
Response model: ListResponse
GET /api/v1/carrier-scrub/runs
Run history (newest first), optionally scoped to one client.
Response model: ListResponse
GET /api/v1/carrier-scrub/formats
Reference: every registered outbound format and its column headers.
Response model: FormatsResponse
GET /api/v1/carrier-scrub/affiliations/stats
Total carrier-affiliation rows per carrier (the removed-customers DB).
Response model: AffiliationStatsResponse
GET /api/v1/carrier-scrub/affiliations
Paginated browse of the person -> carrier affiliation DB.
Response model: AffiliationListResponse
POST /api/v1/carrier-scrub/generate
Count the client's sendable list, (re)create the draft run, and report how many
Response model: GenerateResponse
GET /api/v1/carrier-scrub/runs/{run_id}/parts/{part}/download
Download one ≤cap-row CSV part (built on demand) for a generated run.
Response model: CsvResponse
POST /api/v1/carrier-scrub/send
Generate the carrier file and email it to the client contact, then mark sent.
Response model: ItemResponse
PATCH /api/v1/carrier-scrub/clients/{workspace_name}/config
Set a client's scrub contact email and/or auto-send toggle.
Response model: ItemResponse
GET /api/v1/carrier-scrub/candidates
Active clients not yet scrub-enabled — the pool for the + Add flow.
Response model: ListResponse
POST /api/v1/carrier-scrub/runs/{run_id}/sent
Mark a generated list as sent to the carrier contact.
Response model: ItemResponse
POST /api/v1/carrier-scrub/runs/{run_id}/return
Upload the carrier's survivor file. Computes who was removed (sent − survivors),
Response model: IngestResponse
GET /api/v1/carrier-scrub/runs/{run_id}/removed-csv
Full-record CSV of the contacts the carrier pulled (for archival/analysis).
Response model: CsvResponse
POST /api/v1/carrier-scrub/runs/{run_id}/apply
Exclude the carrier-pulled contacts from the Bison upload and kick off the
Response model: ApplyResponse
Audit
Prefix: /audit | Auth: Auth | Insights reads; POST triggers + /health enforce require_admin per-endpoint
POST /api/v1/audit/discover-campaigns-now
Trigger audit.discover_campaigns immediately.
POST /api/v1/audit/ingest-replies-now
Trigger audit.ingest_replies immediately.
POST /api/v1/audit/ingest-sequence-steps-now
Trigger audit.ingest_sequence_steps.
POST /api/v1/audit/ingest-senders-now
Trigger audit.ingest_senders.
POST /api/v1/audit/attribute-now
Trigger audit.attribute. Classifies audit_origins.outcome.
POST /api/v1/audit/aggregate-rankings-now
Trigger audit.aggregate_rankings.
POST /api/v1/audit/generate-recommendations-now
Trigger audit.generate_recommendations.
POST /api/v1/audit/render-briefings-now
Trigger audit.render_briefings.
POST /api/v1/audit/audience-stats-now
Trigger audit.audience_stats (Phase 4 Audience layer rebuild).
POST /api/v1/audit/refresh-now
Fire the full 8-stage audit chain for one workspace on demand.
GET /api/v1/audit/briefing
Return the latest rendered Markdown briefing for a workspace.
Response model: BriefingResponse
GET /api/v1/audit/recommendations
Return active recommendations (status IN 'new','published') for a workspace.
Response model: List
GET /api/v1/audit/sync-state
Per-stage rollup of audit_sync_state for a workspace.
Response model: List
GET /api/v1/audit/health
Latest run per audit stage from audit_stage_runs (§6 health).
Response model: List
GET /api/v1/audit/step-performance
Per-step performance roll-up for a workspace.
Response model: List
GET /api/v1/audit/leaderboard/subjects
Top subjects by Wilson lower bound for a vertical.
Response model: List
GET /api/v1/audit/leaderboard/pitches
Top pitch fingerprints by Wilson lower bound for a vertical.
Response model: List
GET /api/v1/audit/leaderboard/sender-combos
Top (local_pattern × domain_prefix × domain_suffix × legal) sender combos.
Response model: List
GET /api/v1/audit/audience
Audience layer (Phase 4): reply outcomes by contact segment.
Response model: AudienceStatsResponse
GET /api/v1/audit/verticals
Enabled audit verticals. Drives the vertical-filter dropdown in the UI.
Response model: List
Test
Prefix: /test | Auth: Public
POST /api/v1/test/scrape-no-auth
Create a scraping job WITHOUT authentication (for testing only).
Response model: ScrapingJobResponse
GET /api/v1/test/job/{job_id}
Get job status WITHOUT authentication (for testing only).
Response model: ScrapingJobResponse
GET /api/v1/test/health
Simple health check endpoint.
POST /api/v1/test/process-csv
Manually trigger CSV processing for a job (for testing only).
POST /api/v1/test/verify-emails
Manually trigger email verification for a workspace (for testing only).
GET /api/v1/test/verification-stats/{workspace_name}
Get verification statistics for a workspace (for testing only).
GET /api/v1/test/contacts/raw
Get raw contacts from database (for testing only).
GET /api/v1/test/contacts/verified
Get verified contacts from database (for testing only).
POST /api/v1/test/filter-contacts
Manually trigger contact filtering for a workspace (for testing only).
POST /api/v1/test/generate-batches
Manually trigger weekly batch generation (for testing only).
POST /api/v1/test/upload-batch
Manually trigger Email Bison batch upload (for testing only).
GET /api/v1/test/batch/{batch_id}
Get batch status and details (for testing only).
GET /api/v1/test/pipeline-stats/{workspace_name}
Get complete pipeline statistics for a workspace (for testing only).
Webhooks
Prefix: /webhooks | Auth: Public
POST /api/v1/webhooks/bison
Receive webhook events from Email Bison.
POST /api/v1/webhooks/bison/lead-interested
Dedicated endpoint for lead_interested webhooks.
GET /api/v1/webhooks/bison/health
Health check endpoint for Email Bison webhook.
GET /api/v1/webhooks/bison/stats
Get webhook processing statistics.
GET /api/v1/webhooks/bison/activity
Get recent webhook activity for the activity feed.
Aiark Webhook
Prefix: /aiark | Auth: Public | AI-Ark bulk-export deliveries - shared-secret auth
POST /api/v1/aiark/webhook
Stream an AI-Ark export delivery to disk and ACK immediately after EOF.
Response model: DeliveryReceipt
GET /api/v1/aiark/deliveries
List stored deliveries (newest first).
Response model: DeliveryListResponse
GET /api/v1/aiark/deliveries/{name}
Download one stored delivery payload.
Slack Webhooks
Prefix: /slack | Auth: Public | Slack callbacks - HMAC-signed
POST /api/v1/slack/events
Slack Events API callback. Handles url_verification + message.channels.
POST /api/v1/slack/interactivity
Slack interactive component callback (button clicks, select menus).
Sse
Prefix: `` | Auth: Public | No auth - SSE from authenticated frontend
GET /api/v1/dashboard
SSE endpoint for real-time dashboard updates.
GET /api/v1/clients
Get count of connected SSE clients (admin diagnostic).
Total endpoints discovered: 503