Files
MarketingTool/apps/api

Prospect Platform API — Phase 5 boundary

Dependency-light JSON API for tenant-scoped, manual prospect workflows and the Phase 5 source-ingestion contract. 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. Source queries and adapter results must remain auditable and fail closed; the current runtime does not perform network 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.

Phase 4 jobs and live logging (target contract)

The intended job resource has a stable job_id, tenant/creator metadata, operation/payload fingerprint, status, attempt, timestamps, cancellation state, and terminal error/result metadata. Its lifecycle is queuedrunning → exactly one terminal state: succeeded, failed, or cancelled. State transitions and worker messages must be persisted transactionally with tenant and job identifiers; terminal jobs are immutable except for controlled retention/redaction.

Idempotency and events

Mutating job creation should require an idempotency key (for example, an Idempotency-Key header). The key must be scoped to the authenticated tenant and operation, stored with a request fingerprint, and return the original job/result for an exact replay. Reuse with a different payload must be rejected rather than creating a second job. Idempotency must cover side effects, not merely the HTTP response.

Live events should be append-only and ordered per job with a durable integer sequence/cursor. A consumer can resume from the last acknowledged sequence, tolerate duplicate delivery, and detect gaps. Events must contain only safe operational detail; do not persist passwords, session cookies, API keys, or unnecessary prospect/contact data.

Control and delivery semantics

The MVP job routes are POST /api/v1/jobs, GET /api/v1/jobs, GET /api/v1/jobs/{id}, GET /api/v1/jobs/{id}/events, POST /api/v1/jobs/{id}/cancel, and POST /api/v1/jobs/{id}/retry. They are tenant-scoped and backed by SQLite persistence. Cancellation is best effort and must be race-safe with workers; retry creates a new attempt/lineage and must not repeat completed side effects. Polling supports a bounded cursor and backoff in the web monitor. An SSE endpoint may stream the same persisted sequence events with Last-Event-ID, heartbeats, disconnect/reconnect support, and polling fallback, but SSE is not implemented in this MVP.

The current runtime has no durable job queue and no Redis/Celery integration. Its in-process/SQLite worker is single-instance, non-durable across process loss, and unsuitable for horizontal scaling or guaranteed execution; it is pilot-only.

Phase 5 source adapter contract

Phase 5 treats a source as a registered, reviewable capability rather than an arbitrary URL or scraper. Every adapter contract must identify:

  • a stable adapter/source ID and version, owner, permitted purpose, and terms/robots contact;
  • accepted discovery-query fields, result schema, provenance fields, and validation/error behavior;
  • request and concurrency rate limits, retry/backoff rules, timeout/size bounds, and a retention class for raw source records;
  • health signals and circuit-breaker states (closed, open, half-open), including fail-closed behavior when unhealthy; and
  • an explicit dry_run mode that validates and plans work without contacting a source or writing prospect facts.

The initial safe adapters are csv and manual_reference. CSV input may be parsed and previewed; a manual reference records operator-supplied source identity, citation/reference, observed value, and timestamp. Neither adapter independently verifies a source or authorizes outreach. Raw source records should be retained immutably enough to reproduce the normalized result, with tenant/source/query identifiers, capture time, adapter version, and redaction/retention metadata; never retain secrets or unnecessary personal data.

A source registry entry must include its terms owner, approval status/expiry, allowed tenants or scopes, rate-limit policy, retention class, and health/circuit policy. A discovery query is bounded and tenant-scoped, and its execution mode must be explicit (dry_run by default). A live network source is not implemented and must be rejected unless product, legal, and security approval is recorded and operations explicitly enables the registered adapter. No query, job acceptance, or successful parse may be described as network discovery.

Phase 5 source controls (contract, not current live routes)

Implementations should expose source/query/job state without leaking raw payloads across tenants, including source approval, terms, rate-limit, retention, health, and circuit-open reason. On rate-limit, terms, approval, or circuit failure, return a safe non-live outcome and preserve an audit event; do not silently retry against another source. Dry-run must be side-effect-free with respect to external sources and prospect facts. These are Phase 5 design requirements; the current MVP has no network adapter or discovery endpoint.

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 bounded page/page_size, text q, score_min/score_max, website_class, and pipeline_stage filters, with stable ordering. Responses contain items, page, page_size, and has_next; callers must not assume all records are returned.

  • POST /api/v1/businesses — manual business creation. name is 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, and notes. 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 and production migration work

SQLite is a pilot store with an MVP job/event schema but no production migration runner, durable queue, scheduler, worker lease/recovery, 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. Production migration work must add schema/index hardening and retention policy, tenant-scoped authorization tests, transactional event sequencing, cancellation/retry semantics, observability, and a reviewed Postgres plus durable queue/worker design. Redis/Celery remain future options, not implemented dependencies.