{"openapi":"3.0.3","info":{"title":"Nextract Public API","version":"1.0.0","description":"Inbound integration API for authenticated file uploads, webhooks, and run status polling."},"servers":[{"url":"https://nextract.littleharborlabs.com"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"nex_wh_…"},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"OkResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"ErrorResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["ok","error"]},"IntegrationSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"pathSegment":{"type":"string"},"sourceType":{"type":"string","enum":["api_file_ingest","webhook"]},"endpointUrl":{"type":"string","format":"uri"},"allowedClientCount":{"type":"integer"}}},"WorkflowLifecycleSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PUBLISHED","PAUSED","DISABLED","PENDING_APPROVAL"]},"revision":{"type":"integer"},"nextRunAt":{"type":"string","format":"date-time","nullable":true},"updatedAt":{"type":"string","format":"date-time"},"webhookPathSegment":{"type":"string","nullable":true},"inboundApiPathSegment":{"type":"string","nullable":true}},"required":["id","name","slug","status","revision","updatedAt"]},"WorkflowListResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"organization":{"type":"object","properties":{"slug":{"type":"string"}},"required":["slug"]},"workflows":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowLifecycleSummary"}}},"required":["ok","organization","workflows"]},"WorkflowPublishResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"organization":{"type":"object","properties":{"slug":{"type":"string"}}},"workflowId":{"type":"string"},"status":{"type":"string","enum":["PUBLISHED"]},"revision":{"type":"integer"}},"required":["ok","workflowId","status","revision"]},"WorkflowPauseResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"organization":{"type":"object","properties":{"slug":{"type":"string"}}},"workflowId":{"type":"string"},"status":{"type":"string","enum":["PAUSED"]}},"required":["ok","workflowId","status"]},"PublicDeliveryStatus":{"type":"object","properties":{"kind":{"type":"string","enum":["file","api","connector","storage","database","external_transfer"]},"status":{"type":"string","enum":["success","failed","skipped"]},"destination":{"type":"string"},"httpStatus":{"type":"integer"},"remotePaths":{"type":"array","items":{"type":"string"}},"error":{"type":"string"}}},"PublicRunStatus":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","RUNNING","SUCCESS","FAILED","SKIPPED"]},"workflowId":{"type":"string"},"workflowName":{"type":"string"},"triggeredBy":{"type":"string"},"fileName":{"type":"string","nullable":true},"rowCount":{"type":"integer","nullable":true},"startedAt":{"type":"string","format":"date-time"},"finishedAt":{"type":"string","format":"date-time","nullable":true},"durationMs":{"type":"integer","nullable":true},"error":{"type":"string","nullable":true},"delivery":{"$ref":"#/components/schemas/PublicDeliveryStatus"}}}},"parameters":{"OrgSlug":{"name":"orgSlug","in":"path","required":true,"schema":{"type":"string"}},"PathSegment":{"name":"pathSegment","in":"path","required":true,"schema":{"type":"string"}},"RunId":{"name":"runId","in":"path","required":true,"schema":{"type":"string"}},"SyncQuery":{"name":"sync","in":"query","required":false,"schema":{"type":"boolean"},"description":"When true, process the upload synchronously."},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":256}}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed per minute for this API key."},"RateLimitRemaining":{"schema":{"type":"integer"}},"RateLimitReset":{"schema":{"type":"integer"},"description":"Unix timestamp when the rate limit window resets."}}},"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"paths":{"/api/v1/openapi.json":{"get":{"summary":"OpenAPI document","operationId":"getOpenApiSpec","security":[],"responses":{"200":{"description":"OpenAPI 3.0 JSON document"}}}},"/api/v1/orgs/{orgSlug}/integrations":{"get":{"summary":"List inbound integrations","operationId":"listIntegrations","parameters":[{"$ref":"#/components/parameters/OrgSlug"}],"responses":{"200":{"description":"Published inbound integrations"},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/orgs/{orgSlug}/integrations/{pathSegment}":{"get":{"summary":"Get integration metadata","operationId":"getIntegration","parameters":[{"$ref":"#/components/parameters/OrgSlug"},{"$ref":"#/components/parameters/PathSegment"}],"responses":{"200":{"description":"Integration metadata and upload contract"},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/orgs/{orgSlug}/integrations/{pathSegment}/files":{"post":{"summary":"Upload file","operationId":"uploadFile","parameters":[{"$ref":"#/components/parameters/OrgSlug"},{"$ref":"#/components/parameters/PathSegment"},{"$ref":"#/components/parameters/SyncQuery"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"},"fileName":{"type":"string"}}}}}},"responses":{"200":{"description":"Processed or skipped synchronously"},"202":{"description":"Accepted for asynchronous processing"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"Integration not found"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Processing failed"}}}},"/api/v1/runs/{runId}":{"get":{"summary":"Get run status","operationId":"getRunStatus","parameters":[{"$ref":"#/components/parameters/RunId"}],"responses":{"200":{"description":"Run status including outbound delivery summary","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/OkResponse"},{"type":"object","properties":{"run":{"$ref":"#/components/schemas/PublicRunStatus"}}}]}}}},"401":{"description":"Unauthorized"},"404":{"description":"Run not found"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/orgs/{orgSlug}/workflows":{"get":{"summary":"List integrations (lifecycle)","description":"Lists all non-deleted integrations for the organization (draft, published, paused, disabled, pending approval).","operationId":"listWorkflows","parameters":[{"$ref":"#/components/parameters/OrgSlug"}],"responses":{"200":{"description":"Integration lifecycle summaries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowListResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/orgs/{orgSlug}/workflows/{workflowId}/publish":{"post":{"summary":"Publish or resume an integration","description":"Resumes a paused integration to PUBLISHED. Initial draft publish and dual-control approvals still require Studio.","operationId":"publishWorkflow","parameters":[{"$ref":"#/components/parameters/OrgSlug"},{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Integration is published","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowPublishResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"409":{"description":"Conflict — draft never published, disabled, or awaiting Studio approval"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/orgs/{orgSlug}/workflows/{workflowId}/pause":{"post":{"summary":"Pause a published integration","operationId":"pauseWorkflow","parameters":[{"$ref":"#/components/parameters/OrgSlug"},{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Integration is paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowPauseResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"409":{"description":"Only published integrations can be paused"},"429":{"description":"Rate limit exceeded"}}}},"/api/hooks/{orgSlug}/{pathSegment}":{"post":{"summary":"Ingest webhook payload","operationId":"ingestWebhook","parameters":[{"$ref":"#/components/parameters/OrgSlug"},{"$ref":"#/components/parameters/PathSegment"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}},"text/csv":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Processed"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"Not found"},"429":{"description":"Rate limit exceeded"}}}}},"x-rateLimitDefaultPerMinute":60,"x-maxUploadSizeMb":50}