{"openapi":"3.1.0","info":{"title":"LeadMind API","version":"1.1.0","description":"LeadMind REST API. Errors use `{ error: { code, message, requestId, details? } }`; every response carries `x-request-id`. Rate limits come from your plan (GET /v1/plans) and are reported on every authenticated response via `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (unix seconds); a 429 also carries `Retry-After`. Sandbox keys (`lp_test_…`) return fixture data and never spend credits."},"servers":[{"url":"https://outreach-nlfc.onrender.com"}],"tags":[{"name":"auth"},{"name":"jobs"},{"name":"sources"},{"name":"credits"},{"name":"webhooks"},{"name":"me"},{"name":"apikeys"},{"name":"billing"},{"name":"webhook-endpoints"},{"name":"public"},{"name":"oauth"},{"name":"meta"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Dashboard JWT access token, `lp_live_…` API key, `lp_test_…` sandbox key (fixture data, no credits), or OAuth 2.1 access token."}},"schemas":{"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR","BAD_REQUEST","IDEMPOTENCY_KEY_REQUIRED","IDEMPOTENCY_CONFLICT","UNAUTHENTICATED","INVALID_CREDENTIALS","TOKEN_EXPIRED","TOKEN_INVALID","TOKEN_REUSE_DETECTED","ACCOUNT_LOCKED","FORBIDDEN","INSUFFICIENT_SCOPE","API_KEY_INVALID","API_KEY_DAILY_CAP_EXCEEDED","NOT_FOUND","EMAIL_TAKEN","EMAIL_DISPOSABLE","SIGNUPS_CLOSED","CONFLICT","ILLEGAL_TRANSITION","JOB_NOT_AWAITING_CLARIFICATION","JOB_NOT_DELIVERED","INSUFFICIENT_CREDITS","MAX_CREDITS_EXCEEDED","AMBIGUOUS_PROMPT","NO_SOURCE_AVAILABLE","RATE_LIMITED","CONCURRENT_JOBS_LIMIT","PLAN_LIMIT_EXCEEDED","SUBSCRIPTION_REQUIRED","WEBHOOK_URL_INVALID","SANDBOX_ONLY","LLM_ERROR","LLM_BUDGET_EXCEEDED","APIFY_ERROR","APIFY_TIMEOUT","SCRAPINGDOG_ERROR","STORAGE_ERROR","STRIPE_ERROR","WEBHOOK_SIGNATURE_INVALID","FEATURE_DISABLED","PAYLOAD_TOO_LARGE","INTERNAL"]},"message":{"type":"string"},"requestId":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]},"Job":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"status":{"type":"string","enum":["draft","parsing","awaiting_clarification","routing","scraping","normalizing","analyzing","enriching","delivering","delivered","failed","cancelled"]},"progress":{"type":"number"},"channel":{"type":"string","enum":["web","mcp","api"]},"icpSpec":{"type":["object","null"],"properties":{"industry":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":10},"geo":{"type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":56},"city":{"type":"string","minLength":1,"maxLength":80},"radiusKm":{"type":"number","maximum":200}}},"roles":{"type":"array","items":{"type":"string","maxLength":80},"maxItems":10},"companySize":{"type":"object","properties":{"min":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0}}},"signals":{"type":"array","items":{"type":"string","maxLength":120},"maxItems":10},"filters":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["hasOnlineBooking","hasLiveChat","hasWhatsapp","hasContactForm","hasMetaPixel","hasGoogleAnalytics","hasEcommerce","outdatedSite","isHiring","multiLocation","hasWebsite","hasEmail","hasPhone","cms"]},"value":{"anyOf":[{"type":"boolean"},{"type":"string","maxLength":60}]},"from":{"type":"string","maxLength":120}},"required":["key","value","from"]},"maxItems":10},"count":{"type":"integer","minimum":1,"maximum":5000},"leadType":{"type":"string","enum":["company","person","local_business"]},"ambiguities":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":5,"default":[]}},"required":["industry","geo","count","leadType"]},"clarifyingQuestions":{"type":"array","items":{"type":"string"}},"routing":{"type":["object","null"],"properties":{"candidates":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"score":{"type":"number"},"breakdown":{"type":"object","properties":{"coverageMatch":{"type":"number"},"geoMatch":{"type":"number"},"quality":{"type":"number"},"reliability":{"type":"number"},"costPenalty":{"type":"number"}},"required":["coverageMatch","geoMatch","quality","reliability","costPenalty"]},"eligible":{"type":"boolean"},"reason":{"type":"string"}},"required":["actorId","name","score","breakdown","eligible"]}},"chosen":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"requestedCount":{"type":"integer","minimum":1},"estimatedCostUsd":{"type":"number","minimum":0},"estimatedCredits":{"type":"integer","minimum":0}},"required":["actorId","name","requestedCount","estimatedCostUsd","estimatedCredits"]},"minItems":1},"estimatedCredits":{"type":"integer","minimum":0},"estimatedCostUsd":{"type":"number","minimum":0},"explanation":{"type":"string"},"enrichment":{"type":"object","properties":{"provider":{"type":"string","enum":["scrapingdog"]},"name":{"type":"string"},"enabled":{"type":"boolean"},"reason":{"type":["string","null"]},"maxLookupsPerJob":{"type":"integer","minimum":0},"costPerLookupUsd":{"type":"number","minimum":0},"estimatedMaxCostUsd":{"type":"number","minimum":0}},"required":["provider","name","enabled","reason","maxLookupsPerJob","costPerLookupUsd","estimatedMaxCostUsd"]},"stages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["website_intel","linkedin_fallback"]},"name":{"type":"string"},"enabled":{"type":"boolean"},"reason":{"type":["string","null"]},"limits":{"type":"object","additionalProperties":{"type":"string"}},"estimatedCostUsd":{"type":"number","minimum":0},"expectedCacheHitRate":{"type":["number","null"],"minimum":0,"maximum":1}},"required":["id","name","enabled","reason","limits","estimatedCostUsd","expectedCacheHitRate"]}},"oversourcing":{"type":"object","properties":{"wanted":{"type":"integer"},"requested":{"type":"integer"},"passRate":{"type":"number","minimum":0,"maximum":1},"sampleSize":{"type":"integer"},"filters":{"type":"array","items":{"type":"string"}}},"required":["wanted","requested","passRate","sampleSize","filters"]}},"required":["candidates","chosen","estimatedCredits","estimatedCostUsd","explanation"]},"routedActors":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"requestedCount":{"type":"number"},"runStatus":{"type":"string"},"itemsFetched":{"type":"number"},"itemsValid":{"type":"number"}},"required":["actorId","name","requestedCount","runStatus","itemsFetched","itemsValid"]}},"leadsDelivered":{"type":"number"},"leadsRaw":{"type":"number"},"leadsValid":{"type":"number"},"leadsDeduped":{"type":"number"},"leadsFiltered":{"type":"number","default":0},"creditsHeld":{"type":"number"},"creditsCharged":{"type":"number"},"maxCredits":{"type":["number","null"]},"errorCode":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"costs":{"type":"object","properties":{"llmUsd":{"type":"number"},"apifyUsd":{"type":"number"},"enrichmentUsd":{"type":"number","default":0}},"required":["llmUsd","apifyUsd"]},"timings":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["parse","route","scrape","normalize","intel","enrich","deliver"]},"durationMs":{"type":["number","null"]},"attempts":{"type":"number"},"startedAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["step","durationMs","attempts","startedAt","finishedAt"]}},"etaSeconds":{"type":["number","null"]},"retryAfterSeconds":{"type":["number","null"]},"hasCsv":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"deliveredAt":{"type":["string","null"]}},"required":["id","prompt","status","progress","channel","icpSpec","clarifyingQuestions","routing","routedActors","leadsDelivered","leadsRaw","leadsValid","leadsDeduped","creditsHeld","creditsCharged","maxCredits","errorCode","errorMessage","costs","timings","etaSeconds","retryAfterSeconds","hasCsv","createdAt","updatedAt","deliveredAt"]},"JobSummary":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"status":{"type":"string","enum":["draft","parsing","awaiting_clarification","routing","scraping","normalizing","analyzing","enriching","delivering","delivered","failed","cancelled"]},"progress":{"type":"number"},"channel":{"type":"string","enum":["web","mcp","api"]},"leadsDelivered":{"type":"number"},"creditsCharged":{"type":"number"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","prompt","status","progress","channel","leadsDelivered","creditsCharged","createdAt","updatedAt"]},"Lead":{"type":"object","properties":{"_id":{"type":"string"},"jobId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":200},"company":{"type":"string","maxLength":200},"title":{"type":"string","maxLength":120},"email":{"type":"string","maxLength":254,"format":"email"},"emailVerified":{"type":"boolean","default":false},"phone":{"type":"string","maxLength":40},"website":{"type":"string","maxLength":500,"format":"uri"},"address":{"type":"string","maxLength":400},"city":{"type":"string","maxLength":100},"country":{"type":"string","maxLength":100},"socials":{"type":"object","properties":{"linkedin":{"type":"string","maxLength":300},"instagram":{"type":"string","maxLength":300},"facebook":{"type":"string","maxLength":300},"x":{"type":"string","maxLength":300},"tiktok":{"type":"string","maxLength":300},"youtube":{"type":"string","maxLength":300},"snapchat":{"type":"string","maxLength":300},"telegram":{"type":"string","maxLength":300},"whatsapp":{"type":"string","maxLength":300}}},"source":{"type":"string"},"sourceUrl":{"type":"string","maxLength":1000},"score":{"type":"number","minimum":0,"maximum":100},"scoreReason":{"type":"string","maxLength":200},"site":{"type":"object","properties":{"status":{"type":"string","enum":["ok","no_website","unreachable","robots_blocked","blocked","timeout","error","skipped"]},"domain":{"type":["string","null"],"maxLength":253},"crawlId":{"type":["string","null"],"maxLength":64},"crawledAt":{"type":["string","null"]},"cacheHit":{"type":"boolean"},"pagesCrawled":{"type":"integer","minimum":0},"signals":{"type":["object","null"],"properties":{"hasOnlineBooking":{"type":["boolean","null"]},"bookingProvider":{"type":["string","null"]},"hasLiveChat":{"type":["boolean","null"]},"chatProvider":{"type":["string","null"]},"hasWhatsapp":{"type":"boolean"},"hasContactForm":{"type":"boolean"},"hasMetaPixel":{"type":"boolean"},"hasGoogleAnalytics":{"type":"boolean"},"hasEcommerce":{"type":"boolean"},"cms":{"type":["string","null"]},"hasSsl":{"type":["boolean","null"]},"outdatedSite":{"type":["boolean","null"]},"isHiring":{"type":"boolean"},"multiLocation":{"type":"boolean"},"languages":{"type":"array","items":{"type":"string","maxLength":5},"maxItems":10}},"required":["hasOnlineBooking","bookingProvider","hasLiveChat","chatProvider","hasWhatsapp","hasContactForm","hasMetaPixel","hasGoogleAnalytics","hasEcommerce","cms","hasSsl","outdatedSite","isHiring","multiLocation","languages"]},"tech":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":60},"emailConfidence":{"type":"number","minimum":0,"maximum":1},"phoneConfidence":{"type":"number","minimum":0,"maximum":1}},"required":["status","domain","crawlId","crawledAt","cacheHit","pagesCrawled","signals","tech"]},"filteredBy":{"type":"string","maxLength":60},"dedupeKey":{"type":"string"},"id":{"type":"string"},"createdAt":{"type":"string"}},"required":["_id","jobId","name","source","dedupeKey","id","createdAt"]},"Source":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"coverage":{"type":"array","items":{"type":"string","enum":["local_business","company","person","ecommerce"]}},"geoStrength":{"type":"array","items":{"type":"string"}},"compliance":{"type":"string","enum":["public_data","restricted"]},"enabled":{"type":"boolean"},"qualityScore":{"type":"number","minimum":0,"maximum":1},"reliability":{"type":"number","minimum":0,"maximum":1}},"required":["actorId","name","coverage","geoStrength","compliance","enabled","qualityScore","reliability"]},"User":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"role":{"type":"string"},"emailVerified":{"type":"boolean"},"settings":{"type":"object","properties":{"allowRestrictedSources":{"type":"boolean"},"emailNotifications":{"type":"boolean"}},"required":["allowRestrictedSources","emailNotifications"]},"activatedAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","orgId","email","name","role","emailVerified","settings","activatedAt","createdAt"]},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["live","test"]},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["leads:read","jobs:write","credits:read","webhooks:write"]}},"dailyCreditCap":{"type":"integer"},"spentToday":{"type":"integer"},"lastUsedAt":{"type":["string","null"]},"revokedAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","name","mode","prefix","scopes","dailyCreditCap","spentToday","lastUsedAt","revokedAt","createdAt"]},"CreatedApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string","enum":["live","test"]},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["leads:read","jobs:write","credits:read","webhooks:write"]}},"dailyCreditCap":{"type":"integer"},"spentToday":{"type":"integer"},"lastUsedAt":{"type":["string","null"]},"revokedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"key":{"type":"string"}},"required":["id","name","mode","prefix","scopes","dailyCreditCap","spentToday","lastUsedAt","revokedAt","createdAt","key"]},"CreditBalance":{"type":"object","properties":{"balance":{"type":"integer"},"held":{"type":"integer"},"available":{"type":"integer"},"spentToday":{"type":"integer"},"dailyCap":{"type":["integer","null"]}},"required":["balance","held","available","spentToday","dailyCap"]},"LedgerEntry":{"type":"object","properties":{"id":{"type":"string"},"delta":{"type":"integer"},"reason":{"type":"string","enum":["purchase","hold","release","charge","refund","admin","subscription","expire"]},"jobId":{"type":["string","null"]},"tag":{"type":["string","null"]},"note":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","delta","reason","jobId","tag","note","createdAt"]},"AuthResponse":{"type":"object","properties":{"accessToken":{"type":"string"},"expiresIn":{"type":"integer"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"orgId":{"type":"string"},"emailVerified":{"type":"boolean"},"createdAt":{"type":"string"}},"required":["id","email","name","orgId","emailVerified","createdAt"]}},"required":["accessToken","expiresIn","user"]},"OAuthError":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"}},"required":["error"]},"Plan":{"type":"object","properties":{"id":{"type":"string","enum":["free","starter","growth","scale"]},"name":{"type":"string"},"priceUsd":{"type":"number"},"includedLeads":{"type":"integer"},"perLeadUsd":{"type":["number","null"]},"blurb":{"type":"string"},"limits":{"type":"object","properties":{"requestsPerMinOrg":{"type":"integer"},"requestsPerMinKey":{"type":"integer"},"jobCreatesPerMin":{"type":"integer"},"concurrentJobs":{"type":"integer"},"apiKeys":{"type":"integer"},"webhookEndpoints":{"type":"integer"}},"required":["requestsPerMinOrg","requestsPerMinKey","jobCreatesPerMin","concurrentJobs","apiKeys","webhookEndpoints"]}},"required":["id","name","priceUsd","includedLeads","perLeadUsd","blurb","limits"]},"BillingSummary":{"type":"object","properties":{"plan":{"type":"object","properties":{"id":{"type":"string","enum":["free","starter","growth","scale"]},"name":{"type":"string"},"priceUsd":{"type":"number"},"includedLeads":{"type":"integer"},"perLeadUsd":{"type":["number","null"]},"blurb":{"type":"string"},"limits":{"type":"object","properties":{"requestsPerMinOrg":{"type":"integer"},"requestsPerMinKey":{"type":"integer"},"jobCreatesPerMin":{"type":"integer"},"concurrentJobs":{"type":"integer"},"apiKeys":{"type":"integer"},"webhookEndpoints":{"type":"integer"}},"required":["requestsPerMinOrg","requestsPerMinKey","jobCreatesPerMin","concurrentJobs","apiKeys","webhookEndpoints"]}},"required":["id","name","priceUsd","includedLeads","perLeadUsd","blurb","limits"]},"subscription":{"type":"object","properties":{"status":{"type":"string","enum":["none","trialing","active","past_due","unpaid","canceled","incomplete","incomplete_expired","paused"]},"currentPeriodStart":{"type":["string","null"]},"currentPeriodEnd":{"type":["string","null"]},"cancelAtPeriodEnd":{"type":"boolean"},"entitled":{"type":"boolean"}},"required":["status","currentPeriodStart","currentPeriodEnd","cancelAtPeriodEnd","entitled"]},"usage":{"type":"object","properties":{"includedLeads":{"type":"integer"},"usedThisPeriod":{"type":"integer"},"includedRemaining":{"type":"integer"},"packCredits":{"type":"integer"},"available":{"type":"integer"},"activeApiKeys":{"type":"integer"},"webhookEndpoints":{"type":"integer"},"runningJobs":{"type":"integer"}},"required":["includedLeads","usedThisPeriod","includedRemaining","packCredits","available","activeApiKeys","webhookEndpoints","runningJobs"]},"stripeLive":{"type":"boolean"}},"required":["plan","subscription","usage","stripeLive"]},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]}},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"disabledReason":{"type":["string","null"]},"consecutiveFailures":{"type":"integer"},"lastDeliveryAt":{"type":["string","null"]},"lastStatusCode":{"type":["integer","null"]},"createdAt":{"type":"string"}},"required":["id","url","events","description","enabled","disabledReason","consecutiveFailures","lastDeliveryAt","lastStatusCode","createdAt"]},"CreatedWebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]}},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"disabledReason":{"type":["string","null"]},"consecutiveFailures":{"type":"integer"},"lastDeliveryAt":{"type":["string","null"]},"lastStatusCode":{"type":["integer","null"]},"createdAt":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","events","description","enabled","disabledReason","consecutiveFailures","lastDeliveryAt","lastStatusCode","createdAt","secret"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"endpointId":{"type":"string"},"eventId":{"type":"string"},"eventType":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]},"status":{"type":"string","enum":["pending","succeeded","failed","dead"]},"attempts":{"type":"integer"},"lastStatusCode":{"type":["integer","null"]},"lastError":{"type":["string","null"]},"nextAttemptAt":{"type":["string","null"]},"deliveredAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","endpointId","eventId","eventType","status","attempts","lastStatusCode","lastError","nextAttemptAt","deliveredAt","createdAt"]},"WebhookPayload":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]},"createdAt":{"type":"string"},"test":{"type":"boolean"},"data":{"type":"object","additionalProperties":{}}},"required":["id","type","createdAt","test","data"]},"McpTool_create_lead_job":{"type":"object","properties":{"prompt":{"type":"string","minLength":3,"maxLength":2000,"description":"Natural-language description of the leads wanted, e.g. \"50 gyms in Dubai Marina with phone numbers\"."},"max_credits":{"type":"integer","minimum":1,"maximum":5000,"description":"Optional hard ceiling on credits this job may spend (1 credit = 1 delivered lead). Omit to cap at the available balance; set it when the user named a budget."}},"required":["prompt"]},"McpTool_get_job_status":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^[a-f\\d]{24}$","description":"The jobId returned by create_lead_job."}},"required":["job_id"]},"McpTool_clarify_job":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^[a-f\\d]{24}$","description":"The jobId of a job whose status is awaiting_clarification."},"answers":{"type":"array","items":{"type":"string","minLength":1,"maxLength":500},"minItems":1,"maxItems":5,"description":"One answer per open question from get_job_status, in the same order."}},"required":["job_id","answers"]},"McpTool_get_leads":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^[a-f\\d]{24}$","description":"The jobId returned by create_lead_job."},"cursor":{"type":"string","maxLength":200,"description":"Opaque cursor from the previous page."},"limit":{"type":"integer","minimum":1,"maximum":50,"default":25,"description":"Page size, max 50."}},"required":["job_id"]},"McpTool_export_leads_csv":{"type":"object","properties":{"job_id":{"type":"string","pattern":"^[a-f\\d]{24}$","description":"The jobId returned by create_lead_job."}},"required":["job_id"]},"McpTool_get_credit_balance":{"type":"object","properties":{}},"McpTool_list_sources":{"type":"object","properties":{}}},"parameters":{}},"paths":{"/healthz":{"get":{"tags":["meta"],"summary":"Liveness","responses":{"200":{"description":"Process is up","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"]}}}}}}},"/readyz":{"get":{"tags":["meta"],"summary":"Readiness (mongo, redis, storage, worker)","responses":{"200":{"description":"ok or degraded","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded","down"]},"checks":{"type":"object","additionalProperties":{"type":"string","enum":["ok","fail"]}},"version":{"type":"string"}},"required":["status"]}}}},"503":{"description":"down","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded","down"]},"checks":{"type":"object","additionalProperties":{"type":"string","enum":["ok","fail"]}},"version":{"type":"string"}},"required":["status"]}}}}}}},"/metrics":{"get":{"tags":["meta"],"summary":"Prometheus metrics (HTTP basic auth)","responses":{"200":{"description":"Prometheus text exposition","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Basic auth required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/openapi.json":{"get":{"tags":["meta"],"summary":"This document","responses":{"200":{"description":"OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object","properties":{}}}}}}}},"/v1/auth/register":{"post":{"tags":["auth"],"summary":"Create an account (sets refresh cookie)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","minLength":10,"maxLength":128},"name":{"type":"string","minLength":1,"maxLength":80},"utm":{"type":"object","properties":{"source":{"type":"string","maxLength":100},"medium":{"type":"string","maxLength":100},"campaign":{"type":"string","maxLength":100},"content":{"type":"string","maxLength":100},"term":{"type":"string","maxLength":100},"referrer":{"type":"string","maxLength":500}}}},"required":["email","password"]}}}},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Email already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Signups closed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/login":{"post":{"tags":["auth"],"summary":"Log in (sets refresh cookie)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","minLength":1,"maxLength":128}},"required":["email","password"]}}}},"responses":{"200":{"description":"Logged in","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"423":{"description":"Account locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/refresh":{"post":{"tags":["auth"],"summary":"Rotate the refresh cookie and mint a new access token","responses":{"200":{"description":"Rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, invalid, expired or reused refresh token (cookie cleared)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Revoke the session family and clear the cookie","responses":{"204":{"description":"Logged out"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/forgot-password":{"post":{"tags":["auth"],"summary":"Email a single-use password reset link (always 202; never reveals whether the address exists)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"}},"required":["email"]}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/reset-password":{"post":{"tags":["auth"],"summary":"Set a new password with the emailed token; revokes every session","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":16,"maxLength":128},"password":{"type":"string","minLength":10,"maxLength":128}},"required":["token","password"]}}}},"responses":{"204":{"description":"Password changed — log in again"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Token invalid, already used (TOKEN_INVALID) or expired (TOKEN_EXPIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/verify-email":{"get":{"tags":["auth"],"summary":"Verify email address (redirects to the dashboard)","parameters":[{"schema":{"type":"string","minLength":16,"maxLength":128},"required":true,"name":"token","in":"query"}],"responses":{"302":{"description":"Redirect to PUBLIC_WEB_URL/settings?verified=1|0"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs":{"post":{"tags":["jobs"],"summary":"Create a lead job (async; requires Idempotency-Key)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":200},"required":true,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":3,"maxLength":2000},"maxCredits":{"type":"integer","minimum":1,"maximum":5000}},"required":["prompt"]}}}},"responses":{"202":{"description":"Job accepted (replays return the same job with Idempotent-Replayed: true)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Idempotency-Key reused with a different payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited, or CONCURRENT_JOBS_LIMIT for the plan (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["jobs"],"summary":"List jobs (search, filters, cursor paginated; `total` on the first page)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"},{"schema":{"type":["string","null"]},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"]},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":40},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["web","mcp","api"]},"required":false,"name":"channel","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"q","in":"query"}],"responses":{"200":{"description":"Jobs","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/JobSummary"}},"nextCursor":{"type":["string","null"]},"total":{"type":"integer","minimum":0}},"required":["items","nextCursor"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}":{"get":{"tags":["jobs"],"summary":"Job status","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Job (Retry-After hints polling interval while running)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/internal/website-intel":{"post":{"tags":["internal"],"summary":"Crawl one business website for contacts and signals (Website Intelligence). Internal/QA: 404 unless WEBSITE_INTEL_INTERNAL_ENDPOINT=true; rate-limited per org.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":4,"maxLength":500},"region":{"type":"string","minLength":2,"maxLength":2},"listingPhone":{"type":"string","maxLength":40},"debug":{"type":"boolean","default":false}},"required":["url"]}}}},"responses":{"200":{"description":"WebsiteIntelligence document (see packages/crawler DESIGN.md §2.4)"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Endpoint disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/leads/{leadId}/website":{"get":{"tags":["leads"],"summary":"Website Intelligence behind one lead: projection, full document with provenance, change log","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"leadId","in":"path"}],"responses":{"200":{"description":"{ site, intel, changes }"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/leads/{leadId}/report":{"post":{"tags":["leads"],"summary":"Report a website-derived value as wrong/outdated (learning loop)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"leadId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"field":{"type":"string","enum":["email","phone","whatsapp","social","booking","chat","cms","signal","other"]},"verdict":{"type":"string","enum":["wrong","outdated","correct"]},"value":{"type":"string","maxLength":300},"note":{"type":"string","maxLength":1000}},"required":["field","verdict"]}}}},"responses":{"201":{"description":"{ id }"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/clarify":{"post":{"tags":["jobs"],"summary":"Answer clarifying questions","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"answers":{"type":"array","items":{"type":"string","minLength":1,"maxLength":500},"minItems":1,"maxItems":5}},"required":["answers"]}}}},"responses":{"202":{"description":"Job resumed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Job is not awaiting clarification","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/cancel":{"post":{"tags":["jobs"],"summary":"Cancel a running job (releases held credits)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Job already terminal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/leads":{"get":{"tags":["jobs"],"summary":"Leads for a job (cursor paginated)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Leads","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"nextCursor":{"type":["string","null"]},"total":{"type":"integer","minimum":0}},"required":["items","nextCursor"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/jobs/{id}/export":{"get":{"tags":["jobs"],"summary":"Presigned CSV download URL","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Signed URL (24h)","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string"},"filename":{"type":"string"}},"required":["url","expiresAt","filename"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Job not delivered yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/sources":{"get":{"tags":["sources"],"summary":"Public data sources","responses":{"200":{"description":"Sources","content":{"application/json":{"schema":{"type":"object","properties":{"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"}},"count":{"type":"integer"}},"required":["sources","count"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/credits":{"get":{"tags":["credits"],"summary":"Balance and ledger (filterable, cursor paginated)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"},{"schema":{"type":["string","null"]},"required":false,"name":"from","in":"query"},{"schema":{"type":["string","null"]},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","enum":["purchase","hold","release","charge","refund","admin","subscription","expire"]},"required":false,"name":"reason","in":"query"},{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":false,"name":"jobId","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"q","in":"query"}],"responses":{"200":{"description":"Credits","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"$ref":"#/components/schemas/CreditBalance"},"ledger":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LedgerEntry"}},"nextCursor":{"type":["string","null"]},"total":{"type":"integer","minimum":0}},"required":["items","nextCursor"]}},"required":["balance","ledger"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/credits/checkout":{"post":{"tags":["credits"],"summary":"Start a Stripe Checkout for a credit pack","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"packId":{"type":"string","enum":["starter","growth","scale"]},"successUrl":{"type":"string","format":"uri"},"cancelUrl":{"type":"string","format":"uri"}},"required":["packId"]}}}},"responses":{"200":{"description":"Checkout session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"sessionId":{"type":"string"}},"required":["url","sessionId"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"Payment provider failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhooks/stripe":{"post":{"tags":["webhooks"],"summary":"Stripe events (raw body, stripe-signature header)","parameters":[{"schema":{"type":"string"},"required":true,"name":"stripe-signature","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]},"duplicate":{"type":"boolean"},"type":{"type":"string"}},"required":["received","duplicate","type"]}}}},"400":{"description":"Signature verification failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhooks/apify":{"post":{"tags":["webhooks"],"summary":"Apify run events (x-apify-signature = HMAC(secret, runId))","parameters":[{"schema":{"type":"string"},"required":true,"name":"x-apify-signature","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"eventType":{"type":"string","enum":["ACTOR.RUN.SUCCEEDED","ACTOR.RUN.FAILED","ACTOR.RUN.ABORTED","ACTOR.RUN.TIMED_OUT","ACTOR.RUN.CREATED","ACTOR.RUN.RESURRECTED"]},"eventData":{"type":"object","properties":{"actorId":{"type":"string"},"actorRunId":{"type":"string"}},"required":["actorId","actorRunId"]},"resource":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"defaultDatasetId":{"type":"string"},"usageTotalUsd":{"type":"number"}},"required":["id"]},"createdAt":{"type":"string"}},"required":["eventType","eventData","resource"]}}}},"responses":{"200":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]},"duplicate":{"type":"boolean"},"jobId":{"type":["string","null"]}},"required":["received","duplicate","jobId"]}}}},"400":{"description":"Invalid payload or signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/me":{"get":{"tags":["me"],"summary":"Current user","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"User","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"patch":{"tags":["me"],"summary":"Update profile / settings","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"settings":{"type":"object","properties":{"allowRestrictedSources":{"type":"boolean"},"emailNotifications":{"type":"boolean"}}}}}}}},"responses":{"200":{"description":"User","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/me/data":{"delete":{"tags":["me"],"summary":"GDPR erasure: revoke credentials now, purge asynchronously","security":[{"bearerAuth":[]}],"responses":{"202":{"description":"Purge scheduled","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/apikeys":{"post":{"tags":["apikeys"],"summary":"Create an API key (dashboard sessions only; key shown once)","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"scopes":{"type":"array","items":{"type":"string","enum":["leads:read","jobs:write","credits:read","webhooks:write"]},"minItems":1,"default":["leads:read","jobs:write","credits:read"]},"dailyCreditCap":{"type":"integer","minimum":1,"maximum":100000,"default":500},"mode":{"type":"string","enum":["live","test"],"default":"live"}},"required":["name"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedApiKey"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["apikeys"],"summary":"List API keys","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["items"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/apikeys/{id}":{"delete":{"tags":["apikeys"],"summary":"Revoke an API key","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Revoked"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/plans":{"get":{"tags":["billing"],"summary":"Public plan table (prices, included leads, API limits)","responses":{"200":{"description":"Plans","content":{"application/json":{"schema":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}}},"required":["plans"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/billing":{"get":{"tags":["billing"],"summary":"Current plan, subscription state and this period's usage","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Billing summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSummary"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/billing/subscribe":{"post":{"tags":["billing"],"summary":"Start a subscription (dashboard sessions only) — Stripe Checkout URL, or instant under STRIPE_MOCK","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"planId":{"type":"string","enum":["starter","growth","scale"]},"successUrl":{"type":"string","format":"uri"},"cancelUrl":{"type":"string","format":"uri"}},"required":["planId"]}}}},"responses":{"200":{"description":"Checkout session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"sessionId":{"type":"string"}},"required":["url","sessionId"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Already subscribed: use the portal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"Payment provider failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Stripe customer portal URL (change plan, card, cancel)","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"returnUrl":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Portal session","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"Payment provider failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints":{"post":{"tags":["webhook-endpoints"],"summary":"Register an endpoint (secret returned once)","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]},"minItems":1,"maxItems":5,"default":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]},"description":{"type":"string","maxLength":100}},"required":["url"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedWebhookEndpoint"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["webhook-endpoints"],"summary":"List endpoints","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Endpoints","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["items"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints/{id}":{"get":{"tags":["webhook-endpoints"],"summary":"Endpoint details","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"patch":{"tags":["webhook-endpoints"],"summary":"Update URL, events, description or enabled","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["job.delivered","job.failed","job.awaiting_clarification","job.cancelled","credits.charged"]},"minItems":1,"maxItems":5},"description":{"type":["string","null"],"maxLength":100},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"delete":{"tags":["webhook-endpoints"],"summary":"Delete an endpoint","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints/{id}/rotate-secret":{"post":{"tags":["webhook-endpoints"],"summary":"Rotate the signing secret (new secret returned once)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Endpoint with new secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedWebhookEndpoint"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints/{id}/test":{"post":{"tags":["webhook-endpoints"],"summary":"Queue a test job.delivered event (payload.test = true)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"}],"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"deliveryId":{"type":"string"},"queued":{"type":"boolean","enum":[true]}},"required":["deliveryId","queued"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/webhook-endpoints/{id}/deliveries":{"get":{"tags":["webhook-endpoints"],"summary":"Delivery log (cursor paginated)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-f\\d]{24}$"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"nextCursor":{"type":["string","null"]},"total":{"type":"integer","minimum":0}},"required":["items","nextCursor"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/flags":{"get":{"tags":["public"],"summary":"Public feature flags","responses":{"200":{"description":"Flags","content":{"application/json":{"schema":{"type":"object","properties":{"demo_route_enabled":{"type":"boolean"},"signups_open":{"type":"boolean"},"free_signup_credits":{"type":"integer"},"mcp_oauth_enabled":{"type":"boolean"}},"required":["demo_route_enabled","signups_open","free_signup_credits","mcp_oauth_enabled"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/demo":{"get":{"tags":["public"],"summary":"Sample job + leads for the landing page demo","responses":{"200":{"description":"Demo payload","content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string"},"job":{"type":"object","properties":{"id":{"type":"string"},"prompt":{"type":"string"},"status":{"type":"string","enum":["draft","parsing","awaiting_clarification","routing","scraping","normalizing","analyzing","enriching","delivering","delivered","failed","cancelled"]},"progress":{"type":"number"},"channel":{"type":"string","enum":["web","mcp","api"]},"icpSpec":{"type":["object","null"],"properties":{"industry":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":10},"geo":{"type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":56},"city":{"type":"string","minLength":1,"maxLength":80},"radiusKm":{"type":"number","maximum":200}}},"roles":{"type":"array","items":{"type":"string","maxLength":80},"maxItems":10},"companySize":{"type":"object","properties":{"min":{"type":"integer","minimum":0},"max":{"type":"integer","minimum":0}}},"signals":{"type":"array","items":{"type":"string","maxLength":120},"maxItems":10},"filters":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","enum":["hasOnlineBooking","hasLiveChat","hasWhatsapp","hasContactForm","hasMetaPixel","hasGoogleAnalytics","hasEcommerce","outdatedSite","isHiring","multiLocation","hasWebsite","hasEmail","hasPhone","cms"]},"value":{"anyOf":[{"type":"boolean"},{"type":"string","maxLength":60}]},"from":{"type":"string","maxLength":120}},"required":["key","value","from"]},"maxItems":10},"count":{"type":"integer","minimum":1,"maximum":5000},"leadType":{"type":"string","enum":["company","person","local_business"]},"ambiguities":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":5,"default":[]}},"required":["industry","geo","count","leadType"]},"clarifyingQuestions":{"type":"array","items":{"type":"string"}},"routing":{"type":["object","null"],"properties":{"candidates":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"score":{"type":"number"},"breakdown":{"type":"object","properties":{"coverageMatch":{"type":"number"},"geoMatch":{"type":"number"},"quality":{"type":"number"},"reliability":{"type":"number"},"costPenalty":{"type":"number"}},"required":["coverageMatch","geoMatch","quality","reliability","costPenalty"]},"eligible":{"type":"boolean"},"reason":{"type":"string"}},"required":["actorId","name","score","breakdown","eligible"]}},"chosen":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"requestedCount":{"type":"integer","minimum":1},"estimatedCostUsd":{"type":"number","minimum":0},"estimatedCredits":{"type":"integer","minimum":0}},"required":["actorId","name","requestedCount","estimatedCostUsd","estimatedCredits"]},"minItems":1},"estimatedCredits":{"type":"integer","minimum":0},"estimatedCostUsd":{"type":"number","minimum":0},"explanation":{"type":"string"},"enrichment":{"type":"object","properties":{"provider":{"type":"string","enum":["scrapingdog"]},"name":{"type":"string"},"enabled":{"type":"boolean"},"reason":{"type":["string","null"]},"maxLookupsPerJob":{"type":"integer","minimum":0},"costPerLookupUsd":{"type":"number","minimum":0},"estimatedMaxCostUsd":{"type":"number","minimum":0}},"required":["provider","name","enabled","reason","maxLookupsPerJob","costPerLookupUsd","estimatedMaxCostUsd"]},"stages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["website_intel","linkedin_fallback"]},"name":{"type":"string"},"enabled":{"type":"boolean"},"reason":{"type":["string","null"]},"limits":{"type":"object","additionalProperties":{"type":"string"}},"estimatedCostUsd":{"type":"number","minimum":0},"expectedCacheHitRate":{"type":["number","null"],"minimum":0,"maximum":1}},"required":["id","name","enabled","reason","limits","estimatedCostUsd","expectedCacheHitRate"]}},"oversourcing":{"type":"object","properties":{"wanted":{"type":"integer"},"requested":{"type":"integer"},"passRate":{"type":"number","minimum":0,"maximum":1},"sampleSize":{"type":"integer"},"filters":{"type":"array","items":{"type":"string"}}},"required":["wanted","requested","passRate","sampleSize","filters"]}},"required":["candidates","chosen","estimatedCredits","estimatedCostUsd","explanation"]},"routedActors":{"type":"array","items":{"type":"object","properties":{"actorId":{"type":"string"},"name":{"type":"string"},"requestedCount":{"type":"number"},"runStatus":{"type":"string"},"itemsFetched":{"type":"number"},"itemsValid":{"type":"number"}},"required":["actorId","name","requestedCount","runStatus","itemsFetched","itemsValid"]}},"leadsDelivered":{"type":"number"},"leadsRaw":{"type":"number"},"leadsValid":{"type":"number"},"leadsDeduped":{"type":"number"},"leadsFiltered":{"type":"number","default":0},"creditsHeld":{"type":"number"},"creditsCharged":{"type":"number"},"maxCredits":{"type":["number","null"]},"errorCode":{"type":["string","null"]},"errorMessage":{"type":["string","null"]},"costs":{"type":"object","properties":{"llmUsd":{"type":"number"},"apifyUsd":{"type":"number"},"enrichmentUsd":{"type":"number","default":0}},"required":["llmUsd","apifyUsd"]},"timings":{"type":"array","items":{"type":"object","properties":{"step":{"type":"string","enum":["parse","route","scrape","normalize","intel","enrich","deliver"]},"durationMs":{"type":["number","null"]},"attempts":{"type":"number"},"startedAt":{"type":"string"},"finishedAt":{"type":["string","null"]}},"required":["step","durationMs","attempts","startedAt","finishedAt"]}},"etaSeconds":{"type":["number","null"]},"retryAfterSeconds":{"type":["number","null"]},"hasCsv":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"deliveredAt":{"type":["string","null"]}},"required":["id","prompt","status","progress","channel","icpSpec","clarifyingQuestions","routing","routedActors","leadsDelivered","leadsRaw","leadsValid","leadsDeduped","creditsHeld","creditsCharged","maxCredits","errorCode","errorMessage","costs","timings","etaSeconds","retryAfterSeconds","hasCsv","createdAt","updatedAt","deliveredAt"]},"leads":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"jobId":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":200},"company":{"type":"string","maxLength":200},"title":{"type":"string","maxLength":120},"email":{"type":"string","maxLength":254,"format":"email"},"emailVerified":{"type":"boolean","default":false},"phone":{"type":"string","maxLength":40},"website":{"type":"string","maxLength":500,"format":"uri"},"address":{"type":"string","maxLength":400},"city":{"type":"string","maxLength":100},"country":{"type":"string","maxLength":100},"socials":{"type":"object","properties":{"linkedin":{"type":"string","maxLength":300},"instagram":{"type":"string","maxLength":300},"facebook":{"type":"string","maxLength":300},"x":{"type":"string","maxLength":300},"tiktok":{"type":"string","maxLength":300},"youtube":{"type":"string","maxLength":300},"snapchat":{"type":"string","maxLength":300},"telegram":{"type":"string","maxLength":300},"whatsapp":{"type":"string","maxLength":300}}},"source":{"type":"string"},"sourceUrl":{"type":"string","maxLength":1000},"score":{"type":"number","minimum":0,"maximum":100},"scoreReason":{"type":"string","maxLength":200},"site":{"type":"object","properties":{"status":{"type":"string","enum":["ok","no_website","unreachable","robots_blocked","blocked","timeout","error","skipped"]},"domain":{"type":["string","null"],"maxLength":253},"crawlId":{"type":["string","null"],"maxLength":64},"crawledAt":{"type":["string","null"]},"cacheHit":{"type":"boolean"},"pagesCrawled":{"type":"integer","minimum":0},"signals":{"type":["object","null"],"properties":{"hasOnlineBooking":{"type":["boolean","null"]},"bookingProvider":{"type":["string","null"]},"hasLiveChat":{"type":["boolean","null"]},"chatProvider":{"type":["string","null"]},"hasWhatsapp":{"type":"boolean"},"hasContactForm":{"type":"boolean"},"hasMetaPixel":{"type":"boolean"},"hasGoogleAnalytics":{"type":"boolean"},"hasEcommerce":{"type":"boolean"},"cms":{"type":["string","null"]},"hasSsl":{"type":["boolean","null"]},"outdatedSite":{"type":["boolean","null"]},"isHiring":{"type":"boolean"},"multiLocation":{"type":"boolean"},"languages":{"type":"array","items":{"type":"string","maxLength":5},"maxItems":10}},"required":["hasOnlineBooking","bookingProvider","hasLiveChat","chatProvider","hasWhatsapp","hasContactForm","hasMetaPixel","hasGoogleAnalytics","hasEcommerce","cms","hasSsl","outdatedSite","isHiring","multiLocation","languages"]},"tech":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":60},"emailConfidence":{"type":"number","minimum":0,"maximum":1},"phoneConfidence":{"type":"number","minimum":0,"maximum":1}},"required":["status","domain","crawlId","crawledAt","cacheHit","pagesCrawled","signals","tech"]},"filteredBy":{"type":"string","maxLength":60},"dedupeKey":{"type":"string"},"id":{"type":"string"},"createdAt":{"type":"string"}},"required":["_id","jobId","name","source","dedupeKey","id","createdAt"]}},"sampleData":{"type":"boolean","enum":[true]}},"required":["prompt","job","leads","sampleData"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Demo disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/demo/export.csv":{"get":{"tags":["public"],"summary":"Demo leads as CSV (sandbox exports link here)","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":5000},"required":false,"name":"count","in":"query"}],"responses":{"200":{"description":"CSV","content":{"text/csv":{"schema":{"type":"string"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/data-request":{"post":{"tags":["public"],"summary":"Data-subject request (access / erasure / do-not-sell) for people who appear in lists; adds identifiers to the suppression list","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["delete","access","do_not_sell"]},"email":{"type":"string","maxLength":254,"format":"email"},"website":{"type":"string","maxLength":500},"linkedin":{"type":"string","maxLength":300},"phone":{"type":"string","maxLength":40},"contactEmail":{"type":"string","maxLength":254,"format":"email"},"message":{"type":"string","maxLength":2000}},"required":["type"]}}}},"responses":{"202":{"description":"Recorded","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/feedback":{"post":{"tags":["public"],"summary":"Send product feedback","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","minLength":3,"maxLength":2000},"page":{"type":"string","maxLength":200},"email":{"type":"string","format":"email"}},"required":["message"]}}}},"responses":{"202":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/waitlist":{"post":{"tags":["public"],"summary":"Join the waitlist","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"utm":{"type":"object","properties":{"source":{"type":"string","maxLength":100},"medium":{"type":"string","maxLength":100},"campaign":{"type":"string","maxLength":100},"content":{"type":"string","maxLength":100},"term":{"type":"string","maxLength":100},"referrer":{"type":"string","maxLength":500}}}},"required":["email"]}}}},"responses":{"202":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["oauth"],"summary":"Authorization server metadata (RFC 8414)","responses":{"200":{"description":"Metadata","content":{"application/json":{"schema":{"type":"object","properties":{"issuer":{"type":"string"},"authorization_endpoint":{"type":"string"},"token_endpoint":{"type":"string"},"registration_endpoint":{"type":"string"},"revocation_endpoint":{"type":"string"},"scopes_supported":{"type":"array","items":{"type":"string","enum":["leads:read","jobs:write","credits:read","webhooks:write"]}},"response_types_supported":{"type":"array","items":{"type":"string"}},"grant_types_supported":{"type":"array","items":{"type":"string"}},"code_challenge_methods_supported":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_methods_supported":{"type":"array","items":{"type":"string"}},"service_documentation":{"type":"string"}},"required":["issuer","authorization_endpoint","token_endpoint","registration_endpoint","revocation_endpoint","scopes_supported","response_types_supported","grant_types_supported","code_challenge_methods_supported","token_endpoint_auth_methods_supported","service_documentation"]}}}},"503":{"description":"OAuth disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["oauth"],"summary":"Protected resource metadata (RFC 9728)","responses":{"200":{"description":"Metadata","content":{"application/json":{"schema":{"type":"object","properties":{"resource":{"type":"string"},"authorization_servers":{"type":"array","items":{"type":"string"}},"scopes_supported":{"type":"array","items":{"type":"string","enum":["leads:read","jobs:write","credits:read","webhooks:write"]}},"bearer_methods_supported":{"type":"array","items":{"type":"string"}},"resource_documentation":{"type":"string"}},"required":["resource","authorization_servers","scopes_supported","bearer_methods_supported","resource_documentation"]}}}},"503":{"description":"OAuth disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/oauth/register":{"post":{"tags":["oauth"],"summary":"Dynamic client registration (RFC 7591)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string","minLength":1,"maxLength":100},"redirect_uris":{"type":"array","items":{"type":"string","maxLength":2000,"format":"uri"},"minItems":1,"maxItems":10},"grant_types":{"type":"array","items":{"type":"string","enum":["authorization_code","refresh_token"]}},"response_types":{"type":"array","items":{"type":"string","enum":["code"]}},"token_endpoint_auth_method":{"type":"string","enum":["none","client_secret_post","client_secret_basic"]},"scope":{"type":"string","maxLength":200},"logo_uri":{"type":"string","maxLength":2000,"format":"uri"},"client_uri":{"type":"string","maxLength":2000,"format":"uri"}},"required":["client_name","redirect_uris"]}}}},"responses":{"201":{"description":"Client registered","content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"client_name":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"grant_types":{"type":"array","items":{"type":"string"}},"response_types":{"type":"array","items":{"type":"string"}},"token_endpoint_auth_method":{"type":"string"},"scope":{"type":"string"},"client_id_issued_at":{"type":"integer"}},"required":["client_id","client_name","redirect_uris","grant_types","response_types","token_endpoint_auth_method","scope","client_id_issued_at"]}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"temporarily_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"503":{"description":"OAuth disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/v1/oauth/authorize":{"get":{"tags":["oauth"],"summary":"Authorization endpoint (PKCE S256). Redirects to the dashboard consent page.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100},"required":true,"name":"client_id","in":"query"},{"schema":{"type":"string","maxLength":2000,"format":"uri"},"required":true,"name":"redirect_uri","in":"query"},{"schema":{"type":"string","enum":["code"]},"required":true,"name":"response_type","in":"query"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{43,128}$"},"required":true,"name":"code_challenge","in":"query"},{"schema":{"type":"string","enum":["S256"]},"required":true,"name":"code_challenge_method","in":"query"},{"schema":{"type":"string","maxLength":200},"required":false,"name":"scope","in":"query"},{"schema":{"type":"string","maxLength":500},"required":false,"name":"state","in":"query"},{"schema":{"type":"string","maxLength":2000,"format":"uri"},"required":false,"name":"resource","in":"query"}],"responses":{"302":{"description":"Redirect to consent page (or straight to redirect_uri with a code for an authenticated dashboard session)"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"OAuth disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"tags":["oauth"],"summary":"Consent approval (dashboard JWT) → redirect URL carrying the code","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"client_id":{"type":"string","minLength":1,"maxLength":100},"redirect_uri":{"type":"string","maxLength":2000,"format":"uri"},"response_type":{"type":"string","enum":["code"]},"code_challenge":{"type":"string","pattern":"^[A-Za-z0-9_-]{43,128}$"},"code_challenge_method":{"type":"string","enum":["S256"]},"scope":{"type":"string","maxLength":200},"state":{"type":"string","maxLength":500},"resource":{"type":"string","maxLength":2000,"format":"uri"}},"required":["client_id","redirect_uri","response_type","code_challenge","code_challenge_method"]}}}},"responses":{"200":{"description":"Redirect URL","content":{"application/json":{"schema":{"type":"object","properties":{"redirectUrl":{"type":"string","format":"uri"}},"required":["redirectUrl"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Insufficient scope, or a plan limit (PLAN_LIMIT_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"OAuth disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/oauth/token":{"post":{"tags":["oauth"],"summary":"Token endpoint (authorization_code | refresh_token)","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"oneOf":[{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code"]},"client_id":{"type":"string","minLength":1,"maxLength":100},"client_secret":{"type":"string","maxLength":200},"code":{"type":"string","minLength":1,"maxLength":200},"code_verifier":{"type":"string","pattern":"^[A-Za-z0-9._~-]{43,128}$"},"redirect_uri":{"type":"string","maxLength":2000,"format":"uri"}},"required":["grant_type","client_id","code","code_verifier","redirect_uri"]},{"type":"object","properties":{"grant_type":{"type":"string","enum":["refresh_token"]},"client_id":{"type":"string","minLength":1,"maxLength":100},"client_secret":{"type":"string","maxLength":200},"refresh_token":{"type":"string","minLength":1,"maxLength":200},"scope":{"type":"string","maxLength":200}},"required":["grant_type","client_id","refresh_token"]}]}},"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code"]},"client_id":{"type":"string","minLength":1,"maxLength":100},"client_secret":{"type":"string","maxLength":200},"code":{"type":"string","minLength":1,"maxLength":200},"code_verifier":{"type":"string","pattern":"^[A-Za-z0-9._~-]{43,128}$"},"redirect_uri":{"type":"string","maxLength":2000,"format":"uri"}},"required":["grant_type","client_id","code","code_verifier","redirect_uri"]},{"type":"object","properties":{"grant_type":{"type":"string","enum":["refresh_token"]},"client_id":{"type":"string","minLength":1,"maxLength":100},"client_secret":{"type":"string","maxLength":200},"refresh_token":{"type":"string","minLength":1,"maxLength":200},"scope":{"type":"string","maxLength":200}},"required":["grant_type","client_id","refresh_token"]}]}}}},"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"scope":{"type":"string"}},"required":["access_token","token_type","expires_in","refresh_token","scope"]}}}},"400":{"description":"invalid_grant / invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"invalid_client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"temporarily_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/v1/oauth/revoke":{"post":{"tags":["oauth"],"summary":"Token revocation (RFC 7009)","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":200},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"]},"client_id":{"type":"string","maxLength":100},"client_secret":{"type":"string","maxLength":200}},"required":["token"]}},"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":1,"maxLength":200},"token_type_hint":{"type":"string","enum":["access_token","refresh_token"]},"client_id":{"type":"string","maxLength":100},"client_secret":{"type":"string","maxLength":200}},"required":["token"]}}}},"responses":{"200":{"description":"Revoked (or unknown token)"},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}}},"webhooks":{}}