Nextract

API Reference

Introduction

Public HTTP API for inbound integrations — catalog discovery, authenticated file uploads, and webhook payloads.

Base URL

All paths below are relative to https://nextract.littleharborlabs.com. Replace {orgSlug} with your organization slug (visible in the studio URL and integration settings).

Version 1 — REST catalog

/api/v1/orgs/{orgSlug}/integrations

Discover published inbound integrations and upload files to authenticated API ingest endpoints.

Legacy webhooks

/api/hooks/{orgSlug}/{pathSegment}

POST raw JSON or CSV bodies. The pipeline runs synchronously and returns a run id.

Create API keys in Settings → API Access. Assign authorized clients per integration in the studio when configuring inbound sources. Configuration changes are made in the studio; these endpoints are for runtime traffic only. Queue sources such as Amazon SQS are configured in the studio (Source → Amazon SQS) and polled by the worker — they are not exposed as public HTTP ingest endpoints.

Authentication

Every public API request must include a valid organization API key.

Request headers
Authorization: Bearer nex_wh_…
# or
X-API-Key: nex_wh_…

Keys are prefixed with nex_wh_ and hashed at rest. The full secret is shown once when the key is created.

  • Catalog endpoints — any enabled organization API key.
  • Upload & webhook endpoints — the key must also be authorized on that specific integration in the studio.
  • Disabled keys and keys removed from an integration's allow list receive 401.

Rate limiting

Requests are throttled per organization and API key.

The default limit is 60 requests per minute per API key (or client IP when unauthenticated). Individual API clients may have a lower custom quota configured per API client via the optional rateLimitPerMinute field (when unset, the global default applies). Override the global default with NEXTRACT_PUBLIC_API_RATE_LIMIT_PER_MINUTE on the server.

Successful responses include rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp).

429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Retry-After: 42
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1751836842

{
  "ok": false,
  "error": "Rate limit exceeded"
}

Errors

Error responses use a consistent JSON envelope.

Error body
{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}

Integrations may customize HTTP status codes for auth, validation, not-found, and processing errors on upload and webhook endpoints. Defaults are 401, 400, 404, and 500 respectively.

Integrations API

Read-only catalog of published integrations that accept external traffic.

GEThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/integrations

List inbound integrations

Returns all published integrations with an inbound file API or webhook source. Use this to discover path segments and endpoint URLs for integrators.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug (e.g. acme-inc).

Responses

200

Catalog of inbound integrations.

{
  "ok": true,
  "organization": { "slug": "acme-inc" },
  "integrations": [
    {
      "id": "wf_abc123",
      "name": "Orders inbound",
      "description": "Daily order file intake",
      "pathSegment": "orders-in",
      "sourceType": "api_file_ingest",
      "endpointUrl": "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations/orders-in/files",
      "watchPath": "./organization/acme-inc/inbound/orders-in",
      "glob": "**/*",
      "allowedClientCount": 2
    },
    {
      "id": "wf_def456",
      "name": "Partner webhook",
      "pathSegment": "partner-events",
      "sourceType": "webhook",
      "endpointUrl": "https://nextract.littleharborlabs.com/api/hooks/acme-inc/partner-events",
      "responseFormat": "json",
      "allowedClientCount": 1
    }
  ]
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Organization not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

500

Unexpected server error.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}

Examples

cURL
curl -s \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations"
GEThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/integrations/{pathSegment}

Get integration

Metadata for a single published integration. File-ingest integrations include an upload contract describing required form fields and query parameters.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.
pathSegmentpathstringYesPublic path segment configured on the integration.

Responses

200

Integration metadata (with upload contract when applicable).

{
  "ok": true,
  "integration": {
    "id": "wf_abc123",
    "name": "Orders inbound",
    "pathSegment": "orders-in",
    "sourceType": "api_file_ingest",
    "endpointUrl": "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations/orders-in/files",
    "upload": {
      "method": "POST",
      "contentType": "multipart/form-data",
      "fields": {
        "file": "required — binary file body",
        "fileName": "optional — overrides multipart filename"
      },
      "query": {
        "sync": "optional — true to run the pipeline immediately after upload"
      }
    }
  }
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Organization or integration not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

500

Unexpected server error.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}

Lifecycle API

List, resume, and pause integrations across draft / published / paused / disabled states. Initial draft publish and dual-control approvals remain Studio-only.

GEThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/workflows

List workflows

Returns all non-deleted integrations with status, revision, and schedule metadata.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.

Responses

200

Lifecycle summaries.

{
  "ok": true,
  "organization": { "slug": "acme-inc" },
  "workflows": [
    {
      "id": "wf_abc123",
      "name": "Orders inbound",
      "slug": "orders-inbound",
      "status": "PUBLISHED",
      "revision": 3,
      "nextRunAt": null,
      "updatedAt": "2026-08-01T12:00:00.000Z",
      "webhookPathSegment": null,
      "inboundApiPathSegment": "orders-in"
    }
  ]
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Organization not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

Examples

cURL
curl -s \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/workflows"
POSThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/workflows/{workflowId}/publish

Publish / resume

Resumes a paused integration to PUBLISHED. Drafts that have never been published, disabled integrations, and pending dual-control approvals must be handled in Studio.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.
workflowIdpathstringYesIntegration id.

Responses

200

Integration is published.

{
  "ok": true,
  "organization": { "slug": "acme-inc" },
  "workflowId": "wf_abc123",
  "status": "PUBLISHED",
  "revision": 3
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Integration not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
409

Draft never published, disabled, or awaiting Studio approval.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

POSThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/workflows/{workflowId}/pause

Pause

Pauses a published integration so the worker stops picking up new work.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.
workflowIdpathstringYesIntegration id.

Responses

200

Integration is paused.

{
  "ok": true,
  "organization": { "slug": "acme-inc" },
  "workflowId": "wf_abc123",
  "status": "PAUSED"
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Integration not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
409

Only published integrations can be paused.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

File upload

Multipart upload for integrations using the Authenticated API upload source.

POSThttps://nextract.littleharborlabs.com/api/v1/orgs/{orgSlug}/integrations/{pathSegment}/files

Upload file

Accepts a single file up to 50 MB. The file is stored in the integration inbound using the submitted filename (basename only). By default the worker processes the file asynchronously (HTTP 202). Add ?sync=true to run the pipeline immediately and receive a run id.

Security

ApiKeyAuth (integration allow list)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.
pathSegmentpathstringYesPublic path segment for the file-ingest integration.
syncquerybooleanNoWhen true, process the file synchronously and return run results (HTTP 200).
Idempotency-KeyheaderstringNoReplay the same response for duplicate uploads within 24 hours (per API client and integration).

Request body

Content-Type: multipart/form-dataSingle file upload.

Form fields

NameInTypeRequiredDescription
fileformbinaryYesFile contents. Required.
fileNameformstringNoOverrides the filename from the multipart part.

Responses

202

Accepted — file queued for asynchronous processing (default).

{
  "ok": true,
  "accepted": true,
  "fileName": "invoice.csv"
}
200

Processed synchronously when ?sync=true.

{
  "ok": true,
  "runId": "run_xyz",
  "rowCount": 128,
  "fileName": "invoice.csv"
}
200

Skipped duplicate or idempotent re-delivery (integration-dependent).

{
  "ok": true,
  "skipped": true,
  "reason": "duplicate",
  "fileName": "invoice.csv"
}
400

Invalid multipart body, empty file, or oversize payload.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
401

Missing, invalid, or unauthorized API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Integration not found or not published.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

500

Pipeline processing failed (sync mode).

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}

Examples

Asynchronous upload (default)
curl -X POST \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  -F "[email protected];filename=invoice.csv" \
  "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations/orders-in/files"
Synchronous processing
curl -X POST \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  -F "[email protected]" \
  "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations/orders-in/files?sync=true"
Idempotent upload
curl -X POST \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  -H "Idempotency-Key: invoice-2026-07-06-001" \
  -F "[email protected]" \
  "https://nextract.littleharborlabs.com/api/v1/orgs/acme-inc/integrations/orders-in/files"

Run status

Poll pipeline runs returned from synchronous uploads and webhooks. Includes outbound delivery status.

GEThttps://nextract.littleharborlabs.com/api/v1/runs/{runId}

Get run status

Returns run lifecycle fields, per-step summaries, and outbound delivery metadata (API, connector, storage, database, or external file transfer destinations). File paths on disk are not exposed — only the inbound file name.

Security

ApiKeyAuth (organization)

Parameters

NameInTypeRequiredDescription
runIdpathstringYesRun id from a synchronous upload or webhook response.

Responses

200

Run status with delivery summary.

{
  "ok": true,
  "run": {
    "id": "run_xyz",
    "status": "SUCCESS",
    "workflowId": "wf_abc123",
    "workflowName": "Orders inbound",
    "triggeredBy": "api_file_ingest",
    "fileName": "invoice.csv",
    "rowCount": 128,
    "startedAt": "2026-07-06T18:00:00.000Z",
    "finishedAt": "2026-07-06T18:00:04.000Z",
    "durationMs": 4000,
    "error": null,
    "delivery": {
      "kind": "api",
      "status": "success",
      "destination": "https://api.example.com/orders",
      "httpStatus": 201,
      "format": "json"
    },
    "steps": [
      { "stepId": "parse-1", "stepType": "parse", "status": "SUCCESS", "error": null, "delivery": null },
      {
        "stepId": "load-1",
        "stepType": "load_api_endpoint",
        "status": "SUCCESS",
        "error": null,
        "delivery": {
          "kind": "api",
          "status": "success",
          "destination": "https://api.example.com/orders",
          "httpStatus": 201,
          "format": "json"
        }
      }
    ]
  }
}
401

Missing or invalid API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Run not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

Examples

cURL
curl -s \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  "https://nextract.littleharborlabs.com/api/v1/runs/run_xyz"

Webhooks

POST raw JSON or CSV payloads to legacy webhook endpoints.

POSThttps://nextract.littleharborlabs.com/api/hooks/{orgSlug}/{pathSegment}

Ingest webhook payload

Raw request body (not multipart). The payload is staged to CSV and the pipeline runs synchronously. Configure path segment, body format, authorized clients, and optional custom HTTP status codes on a webhook source integration in the studio.

Security

ApiKeyAuth (integration allow list)

Parameters

NameInTypeRequiredDescription
orgSlugpathstringYesOrganization slug.
pathSegmentpathstringYesWebhook path segment configured on the integration.

Request body

Content-Type: application/json | text/csvRaw body matching the integration's configured response format.

Responses

200

Processed successfully.

{
  "ok": true,
  "runId": "run_xyz",
  "rowCount": 4
}
200

Skipped (e.g. duplicate detection).

{
  "ok": true,
  "skipped": true,
  "reason": "duplicate"
}
400

Empty body or invalid payload.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
401

Missing, invalid, or unauthorized API key.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
404

Webhook endpoint not found.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}
429

Rate limit exceeded.

500

Pipeline processing failed.

{
  "ok": false,
  "error": "Invalid or unauthorized API key"
}

Examples

JSON webhook
curl -X POST \
  -H "Authorization: Bearer $NEXTRACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orders":[{"id":"A1","total":42}]}' \
  "https://nextract.littleharborlabs.com/api/hooks/acme-inc/partner-events"

Alert webhooks (outbound)

Nextract can POST event notifications to URLs you configure under Settings → Alerts.

These are outbound callbacks from Nextract to your systems — not inbound integration endpoints. Payloads are JSON with an event field and organization context.

Event payloads
// run.failed
{
  "event": "run.failed",
  "organizationId": "…",
  "workflowId": "…",
  "runId": "…",
  "error": "…"
}

// quarantine.file
{
  "event": "quarantine.file",
  "organizationId": "…",
  "workflowId": "…",
  "fileName": "…",
  "reasonCode": "MALWARE_DETECTED",
  "quarantinePath": "…"
}

// connector.auth_failed
{
  "event": "connector.auth_failed",
  "organizationId": "…",
  "workflowId": "…",
  "connectorId": "stripe",
  "error": "…"
}

OpenAPI

Machine-readable API description for codegen and API gateways.

OpenAPI 3.0 document

Download the spec at https://nextract.littleharborlabs.com/api/v1/openapi.json. The document lists all public paths, security schemes, and response schemas including PublicRunStatus, PublicDeliveryStatus, and lifecycle schemas (WorkflowLifecycleSummary).

TypeScript SDK

Generated client for the public API, including lifecycle helpers.

@nextract/sdk

The monorepo package @nextract/sdk wraps OpenAPI paths with openapi-fetch. Refresh types after API changes with npm run sdk:generate.

Lifecycle helpers
import { createNextractClient } from "@nextract/sdk";

const api = createNextractClient({
  baseUrl: "https://nextract.littleharborlabs.com",
  apiKey: process.env.NEXTRACT_API_KEY!,
});

const { data } = await api.listWorkflows("acme-inc");
await api.pauseWorkflow("acme-inc", "wf_abc123");
await api.publishWorkflow("acme-inc", "wf_abc123");

Studio setup

How to expose an integration on the public API.

  1. Create an integration and choose Incoming files → Authenticated API upload or a Webhook source.
  2. Set the public path segment and assign one or more API clients from API Access.
  3. Publish the integration — only published workflows appear in the catalog.
  4. Share the endpoint URL from the integration editor or discover it via GET /integrations.
Environments

DEV / QA / STAGING / PROD stages

Connectors

OAuth and API-key connections

Quarantine

Review isolated inbound files

Alerts

Failure and quarantine notifications