{"openapi":"3.1.0","info":{"title":"Skewix Forensic Reconciliation & Signal Recovery API","description":"Skewix's 8-Connector Forensic Reconciliation & CAPI Signal Recovery API for 3-way Ad-Spend-to-Cash tie-outs, server-side conversion backfill (Meta CAPI v19.0 & Google Ads OCI), 1st-party edge click collection, and automated CFO reporting workflows. Authenticate with session cookies/Bearer JWT or programmatic API keys (X-API-Key header).","version":"2026.05","contact":{"name":"Skewix Forensic Engineering","email":"support@skewix.com"}},"servers":[{"url":"https://app.skewix.com","description":"Current server"},{"url":"https://skewix.com","description":"Production Edge Server"},{"url":"http://localhost:3000","description":"Local Development Server"}],"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Session or Clerk JWT bearer token"},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Workspace programmatic API key (prefix: skw_)"}},"schemas":{"Connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"platform":{"type":"string","enum":["stripe","hubspot","google_ads","meta_ads","google_analytics","linkedin_ads","tiktok_ads","microsoft_ads"]},"name":{"type":"string"},"status":{"type":"string","enum":["active","error","disconnected"]},"healthScore":{"type":"integer","minimum":0,"maximum":100},"lastSyncAt":{"type":"string","format":"date-time","nullable":true},"requiresAccountSelection":{"type":"boolean"},"dataCoverage":{"type":"object","properties":{"totalRows":{"type":"integer"},"campaignCount":{"type":"integer"},"dateFrom":{"type":"string","format":"date","nullable":true},"dateTo":{"type":"string","format":"date","nullable":true},"totalSpend":{"type":"number"}}},"createdAt":{"type":"string","format":"date-time"}}},"Dataset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"connections":{"type":"array","items":{"type":"string","format":"uuid"}},"lastReconAt":{"type":"string","format":"date-time","nullable":true},"readiness":{"type":"object","properties":{"status":{"type":"string","enum":["ready","needs_connections","needs_data"]},"isReady":{"type":"boolean"},"connectionCount":{"type":"integer"},"readyConnectionCount":{"type":"integer"},"connectionsWithRows":{"type":"integer"},"totalRows":{"type":"integer"},"campaignCount":{"type":"integer"},"dateFrom":{"type":"string","format":"date","nullable":true},"dateTo":{"type":"string","format":"date","nullable":true},"message":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time"}}},"ReconRun":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"datasetId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"startedAt":{"type":"string","format":"date-time","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true},"discrepanciesFound":{"type":"integer"},"varianceThreshold":{"type":"string"},"reportReadiness":{"type":"string","enum":["clean","needs_review","blocked","approved"]},"reportDecision":{"type":"string","enum":["pending","approved","blocked"]},"reportDecisionAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Discrepancy":{"type":"object","properties":{"metric":{"type":"string","enum":["spend","impressions","clicks","conversions","revenue"]},"platformA":{"type":"string"},"platformB":{"type":"string"},"campaignId":{"type":"string"},"varianceAbsolute":{"type":"number"},"variancePercent":{"type":"number"},"severity":{"type":"string","enum":["high","medium","low"]},"detectedAt":{"type":"string","format":"date-time"}}},"ReconciliationIssue":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reconRunId":{"type":"string","format":"uuid"},"datasetId":{"type":"string","format":"uuid"},"campaignId":{"type":"string"},"platformA":{"type":"string"},"platformB":{"type":"string"},"dateFrom":{"type":"string","format":"date"},"dateTo":{"type":"string","format":"date"},"severity":{"type":"string","enum":["high","medium","low"]},"status":{"type":"string","enum":["needs_review","reviewed","resolved","ignored"]},"materialityScore":{"type":"number"},"estimatedSpendImpact":{"type":"number"},"maxVariancePercent":{"type":"number"},"affectedMetrics":{"type":"array","items":{"type":"object"}},"recurrenceCount":{"type":"integer"},"lastSeenAt":{"type":"string","format":"date-time","nullable":true}}},"ScheduledExport":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string","enum":["csv","json"]},"entityType":{"type":"string","enum":["reconciliation_issues","reporting_issues","discrepancies"]},"frequency":{"type":"string","enum":["daily","weekly","monthly"]},"status":{"type":"string"},"nextRunAt":{"type":"string","format":"date-time","nullable":true},"lastRunAt":{"type":"string","format":"date-time","nullable":true},"lastRunStatus":{"type":"string","nullable":true},"runCount":{"type":"integer"}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"keyPrefix":{"type":"string"},"scope":{"type":"string","enum":["read","write","admin"]},"status":{"type":"string","enum":["active","expired","revoked"]},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"statusCode":{"type":"integer"},"statusMessage":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/api/connections":{"get":{"summary":"List 8-connector workspace integrations","description":"Returns all configured ad platform, HubSpot CRM, and Stripe cash ledger connections along with data coverage and sync health.","tags":["Connections"],"responses":{"200":{"description":"List of connections","content":{"application/json":{"schema":{"type":"object","properties":{"connections":{"type":"array","items":{"$ref":"#/components/schemas/Connection"}}}}}}}}},"post":{"summary":"Create connection","description":"Registers a new connector integration (Stripe, HubSpot, Meta Ads, Google Ads, GA4, TikTok Ads, LinkedIn Ads, or Microsoft Ads).","tags":["Connections"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["stripe","hubspot","google_ads","meta_ads","google_analytics","linkedin_ads","tiktok_ads","microsoft_ads"]},"name":{"type":"string"}},"required":["platform","name"]}}}},"responses":{"201":{"description":"Connection created"}}}},"/api/datasets":{"get":{"summary":"List forensic datasets","description":"Returns multi-source datasets configured for 3-way Ad-Spend-to-Cash reconciliation.","tags":["Datasets"],"responses":{"200":{"description":"List of datasets","content":{"application/json":{"schema":{"type":"object","properties":{"datasets":{"type":"array","items":{"$ref":"#/components/schemas/Dataset"}}}}}}}}}},"/api/recon":{"get":{"summary":"List forensic tie-out & reporting QA runs","description":"Returns historical and active reconciliation runs across your datasets.","tags":["Reporting QA"],"responses":{"200":{"description":"List of reporting QA runs","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/ReconRun"}}}}}}}}},"post":{"summary":"Execute 3-way forensic tie-out run","description":"Initiates a reconciliation run comparing ad spend, analytics conversions, and verified Stripe/HubSpot cash.","tags":["Reporting QA"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"datasetId":{"type":"string","format":"uuid"},"dateFrom":{"type":"string","format":"date"},"dateTo":{"type":"string","format":"date"},"threshold":{"type":"number","minimum":0,"maximum":1}},"required":["datasetId","dateFrom","dateTo"]}}}},"responses":{"200":{"description":"Reporting QA run started"}}}},"/api/recon/{id}":{"get":{"summary":"Get reporting QA run details","description":"Returns run metadata, persisted reporting issues, raw variance rows, and recurrence context.","tags":["Reporting QA"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Reporting QA run details","content":{"application/json":{"schema":{"type":"object","properties":{"run":{"$ref":"#/components/schemas/ReconRun"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/ReconciliationIssue"}},"discrepancies":{"type":"array","items":{"$ref":"#/components/schemas/Discrepancy"}}}}}}},"404":{"description":"Reporting QA run not found"}}}},"/api/recon/{id}/decision":{"put":{"summary":"Set executive report sign-off decision","description":"Approve, block, or reopen a forensic audit run after materiality review.","tags":["Reporting QA"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"decision":{"type":"string","enum":["pending","approved","blocked"]},"note":{"type":"string","maxLength":1000}},"required":["decision"]}}}},"responses":{"200":{"description":"Report decision updated"},"400":{"description":"Validation error"},"404":{"description":"Reporting QA run not found"}}}},"/api/issues/{id}":{"put":{"summary":"Update reporting issue status","description":"Transition an issue between needs_review, reviewed, resolved, or ignored.","tags":["Reporting QA"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["needs_review","reviewed","resolved","ignored"]}},"required":["status"]}}}},"responses":{"200":{"description":"Issue status updated"},"404":{"description":"Issue not found"}}}},"/api/recovery/dispatch":{"post":{"summary":"Dispatch CAPI & Offline Conversion signal recovery","description":"Hashes customer PII via SHA-256 and dispatches unattributed Stripe/HubSpot cash conversions back to Meta Conversions API (v19.0) or Google Ads Offline Conversion Import (OCI).","tags":["Forensic Recovery"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"issueId":{"type":"string","format":"uuid"},"targetPlatform":{"type":"string","enum":["meta_ads","google_ads"]},"eventName":{"type":"string","default":"Purchase"},"conversions":{"type":"array","items":{"type":"object","properties":{"eventId":{"type":"string"},"value":{"type":"number"},"currency":{"type":"string","default":"USD"},"clickId":{"type":"string","description":"fbclid or gclid"},"emailHash":{"type":"string","description":"SHA-256 normalized email digest"}}}}},"required":["targetPlatform"]}}}},"responses":{"200":{"description":"Conversion recovery payload dispatched","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"eventsDispatched":{"type":"integer"},"targetPlatform":{"type":"string"},"receiptId":{"type":"string"}}}}}}}}},"/api/collect/script.js":{"get":{"summary":"1st-Party Edge Click Collector snippet","description":"Serves the lightweight first-party edge JavaScript snippet that captures fbclid, gclid, ttclid, li_fat_id, and msclkid into first-party storage and decorates Stripe checkout forms.","tags":["Forensic Recovery"],"security":[],"parameters":[{"name":"tenantId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JavaScript collector bundle","content":{"application/javascript":{"schema":{"type":"string"}}}}}}},"/api/webhooks/stripe-revenue":{"post":{"summary":"Inbound Stripe Cash Ledger webhook","description":"Ingests real-time Stripe charge.succeeded, charge.refunded, and payment_intent.succeeded events to reconcile net settled cash against ad platform conversions.","tags":["Webhooks"],"parameters":[{"name":"tenantId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["charge.succeeded","charge.refunded","payment_intent.succeeded"]},"data":{"type":"object"}},"required":["type","data"]}}}},"responses":{"200":{"description":"Stripe cash webhook processed and attributed","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean"},"eventType":{"type":"string"},"attributedCampaign":{"type":"string","nullable":true}}}}}}}}},"/api/reports/{runId}.pdf":{"get":{"summary":"Download CFO-ready audit PDF","description":"Generates an executive PDF sign-off certificate for a completed reconciliation run.","tags":["Exports"],"parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PDF report","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"Upgrade required"},"404":{"description":"Reporting QA run not found"}}}},"/api/discrepancies/export":{"get":{"summary":"Export raw variance rows (CSV/JSON)","description":"Exports CSV or JSON variance rows filtered by severity, platform, or campaign.","tags":["Exports"],"parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["csv","json"],"default":"json"}},{"name":"severity","in":"query","schema":{"type":"string","enum":["high","medium","low"]}},{"name":"platform","in":"query","schema":{"type":"string"}},{"name":"campaignId","in":"query","schema":{"type":"string"}},{"name":"datasetId","in":"query","schema":{"type":"string"}},{"name":"dateFrom","in":"query","schema":{"type":"string","format":"date"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Export file or JSON payload"},"403":{"description":"Upgrade required"}}}},"/api/issues/export":{"get":{"summary":"Export forensic reporting QA issues","description":"Exports campaign-level reporting issues with materiality, review status, and source setting gaps.","tags":["Exports"],"parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["csv","json"],"default":"json"}},{"name":"reconRunId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"datasetId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["needs_review","reviewed","resolved","ignored"]}},{"name":"severity","in":"query","schema":{"type":"string","enum":["high","medium","low"]}}],"responses":{"200":{"description":"Export file or JSON payload"},"403":{"description":"Upgrade required"},"404":{"description":"Reporting QA run not found"}}}},"/api/exports":{"get":{"summary":"List scheduled CFO exports","description":"Returns recurring CSV/JSON export schedules configured for the workspace.","tags":["Exports"],"responses":{"200":{"description":"List of scheduled exports","content":{"application/json":{"schema":{"type":"object","properties":{"exports":{"type":"array","items":{"$ref":"#/components/schemas/ScheduledExport"}}}}}}},"403":{"description":"Upgrade required"}}},"post":{"summary":"Create scheduled CFO export","description":"Creates a recurring CSV/JSON export for forensic issues or variance rows.","tags":["Exports"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"format":{"type":"string","enum":["csv","json"],"default":"csv"},"entityType":{"type":"string","enum":["reconciliation_issues","reporting_issues","discrepancies"]},"filters":{"type":"object"},"frequency":{"type":"string","enum":["daily","weekly","monthly"]},"dayOfWeek":{"type":"integer","minimum":0,"maximum":6},"dayOfMonth":{"type":"integer","minimum":1,"maximum":31},"hourOfDay":{"type":"integer","minimum":0,"maximum":23,"default":9},"timezone":{"type":"string","default":"UTC"},"emailRecipients":{"type":"array","items":{"type":"string","format":"email"}}},"required":["name","entityType","frequency"]}}}},"responses":{"200":{"description":"Scheduled export created"},"400":{"description":"Validation error"},"403":{"description":"Upgrade required"}}}},"/api/exports/{id}":{"delete":{"summary":"Delete scheduled export","description":"Removes a recurring export schedule.","tags":["Exports"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Scheduled export deleted"},"403":{"description":"Upgrade required"},"404":{"description":"Export not found"}}}},"/api/keys":{"get":{"summary":"List workspace API keys","description":"Returns active, expired, and revoked API key metadata.","tags":["API Keys"],"responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}}}},"post":{"summary":"Create programmatic API key","description":"Mints a new skw_ API key and returns the plaintext token once.","tags":["API Keys"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["read","write","admin"]},"expiresInDays":{"type":"integer","default":365}},"required":["name"]}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"},"scope":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/keys/{id}":{"delete":{"summary":"Revoke API key","description":"Immediately revokes an active API key.","tags":["API Keys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"API key revoked"}}}},"/api/quality/health":{"get":{"summary":"Get 8-connector data quality & sync telemetry","description":"Computes real-time sync recency, error rate, and overall health scores across all connected ad platforms, CRM, and Stripe ledgers.","tags":["System"],"responses":{"200":{"description":"Connector telemetry & anomaly report","content":{"application/json":{"schema":{"type":"object","properties":{"overallHealth":{"type":"integer","minimum":0,"maximum":100},"connections":{"type":"array","items":{"type":"object"}},"anomalies":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/dashboard/stats":{"get":{"summary":"Get workspace forensic telemetry stats","description":"Returns aggregate connection health and 30-day variance trend metrics.","tags":["System"],"responses":{"200":{"description":"Dashboard statistics","content":{"application/json":{"schema":{"type":"object","properties":{"connections":{"type":"object","properties":{"total":{"type":"integer"},"healthy":{"type":"integer"},"errored":{"type":"integer"}}},"discrepancies":{"type":"object","properties":{"totalLast30Days":{"type":"integer"},"severityBreakdown":{"type":"object"},"trend":{"type":"array","items":{"type":"object"}}}}}}}}}}}},"/api/health":{"get":{"summary":"Edge infrastructure health check","description":"Verifies Cloudflare D1 ledger, Workers AI binding, KV cache, and rate limiter availability.","tags":["System"],"security":[],"responses":{"200":{"description":"System health status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded"]},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object"}}}}}}}}}}}