Prospect Platform API — Phase 3
Dependency-light JSON API for tenant-scoped, manual prospect workflows. Core domain rules use Python's standard library and persistence is SQLite. The API stores businesses plus child intelligence/evidence records, pipeline state, notes, and audit context. It never performs automated discovery, DNS/website scanning, or outreach.
Run
From this directory:
python3 app/main.py
# listens on http://127.0.0.1:8000
python3 -m unittest discover
Set PROSPECT_API_PORT or pass --port; set PROSPECT_API_DB or pass --db to override the default prospects.db.
Endpoint contract
All protected endpoints require the server-side session cookie. Every query is constrained by the authenticated user's organization_id; IDs from another tenant behave as not found and must not disclose whether a record exists.
Health and workspace
GET /api/v1/health/live— unauthenticated liveness check.GET /api/v1/auth/me— current authenticated user and tenant.GET /api/v1/dashboard/summary— tenant-scoped counts and score summary.
Prospect and child intelligence records
-
GET /api/v1/businesses— paginated tenant list. Supports boundedpage/page_size, textq,score_min/score_max,website_class, andpipeline_stagefilters, with stable ordering. Responses containitems,page,page_size, andhas_next; callers must not assume all records are returned. -
POST /api/v1/businesses— manual business creation.nameis required; website, email, phone, description, and other explicitly supported intake fields are optional. Normalization, scoring, deduplication, and suppression are enforced server-side. -
GET /api/v1/businesses/{id}— tenant-scoped business detail, including the permitted child intelligence/evidence projection and current pipeline/review context. The business detail includes the supported child collections:contacts,domains,websites,evidence,pipeline, andnotes. The child collection routes are: -
POST /api/v1/businesses/{id}/contacts— manually add a contact; suppression matching marks a matching contact as do-not-contact. -
POST /api/v1/businesses/{id}/domains— manually add a domain observation. -
POST /api/v1/businesses/{id}/websites— manually add a website observation/classification. -
POST /api/v1/businesses/{id}/evidence— manually add evidence with its kind, claim, and source URL/reference. This records provenance supplied by the operator; it does not scan or independently verify the URL. -
POST /api/v1/businesses/{id}/notes— add a manual note.
Child records are subordinate to their parent business. A child ID is never sufficient authorization: the API verifies both the child ID and the parent business's organization. Do not use a missing source or a score as proof that a website or DNS check occurred.
Pipeline, verification, and audit behavior
POST /api/v1/businesses/{id}/pipeline— record an allowed human workflow-stage transition, with server-side validation and an audit event.POST /api/v1/businesses/{id}/verify— record the permitted human verification action and its audit event; it does not perform an external check.- Each business detail response returns the tenant-scoped child collections and current verification/pipeline context. Audit events are retained in the workspace audit log; the detail projection includes the relevant mutation context where supported.
Pipeline state and verification are review metadata, not outreach authorization. Suppression always wins, and the API exposes no send/contact endpoint. State changes, child records, and notes are human-entered; they do not trigger discovery, scanning, or outbound messaging.
Existing safety and intake routes
POST /api/v1/suppressions— add{kind: email|domain|phone, value: ...}for the current tenant. Future matching business creation is blocked.POST /api/v1/imports/preview— preview{rows: [...]}without writing; reports accepted, duplicates, suppressed, and normalized rows. It is not an import/persistence endpoint.
All SQL uses parameters and all responses are JSON. Scores include score_version and score_factors for traceability. Provenance is supplied by the operator/source record; the MVP does not validate external sources or independently refresh evidence.
Pagination and filtering rules
List and child-record endpoints are deliberately bounded. For business lists, use page (starting at 1) and page_size within the server-enforced maximum; invalid values are rejected rather than allowing an unbounded query. Supported filters are applied inside the tenant-scoped query before pagination: q, score_min, score_max, website_class, and pipeline_stage. The UI's page and filter controls are convenience clients, not authorization controls. A filtered page is not a count of the entire unfiltered tenant unless the response explicitly says so.
Remaining limitations
SQLite is a pilot store with no production migration runner, queue, scheduler, durable backup command, or tested restore workflow. Authentication currently uses a development password fallback and does not by itself provide production Argon2id, MFA, CSRF protection, rate limiting, or a complete retention-grade audit system. Automated discovery, DNS/HTTP scanning, and outreach remain explicitly out of scope.