Skip to main content

Overview

The @filefeed/sdk package provides a type-safe client for the FileFeed API.
  • Authentication via API key
  • Resources: Connections (formerly Clients), Pipelines, Schemas, Pipeline Runs, Webhooks, Outbound Uploads, Documents, Files, Notifications
  • Pagination helpers and typed responses

API Reference

Explore endpoints with the API Playground.

Syncing Data

Fetch processed data and acknowledge runs.

Handling Errors

Retry patterns and structured error handling.

Installation

npm install @filefeed/sdk

Requirements

  • Node.js >= 18
  • TypeScript >= 5 (for TS projects)

Initialize the client

import FileFeed from '@filefeed/sdk';

const filefeed = new FileFeed({ apiKey: process.env.FILEFEED_API_KEY! });
// Example usage
const runs = await filefeed.pipelineRuns.list({ status: 'completed', limit: 50 });

Next steps

Resources and methods

For endpoint details and payload schemas, see the API Reference.
Manage SFTP / Email endpoints (formerly called clients). The deprecated filefeed.clients.* namespace still works and proxies here.
MethodSignatureDescription
listlist()List connections.
retrieveretrieve(id)Get a connection by id.
getByNamegetByName(name)Get a connection by name (unique per workspace). Resolves to the connection or undefined.
createcreate(params)Create a connection (SFTP, self-hosted SFTP, or type: 'EMAIL').
updateupdate(id, params)Update connection details.
removeremove(id)Delete a connection.
testtest(id)Test SFTP connectivity (returns success/message). No-op for EMAIL.
Common workflows
  • Provision a connection with SFTP credentials (write-only — never read back)
  • Create an EMAIL connection that ingests mailed attachments
  • Verify connectivity before onboarding
  • Resolve a connection by its human-readable name
const conn = await filefeed.connections.create({ name: 'Acme' });
const ok = await filefeed.connections.test(conn.id);

// Outbound uploads reference a connection by its human-readable NAME —
// pass `connectionName: 'Acme'` directly (no slug lookup needed).
// Credentials are never returned on reads.
const found = await filefeed.connections.getByName('Acme');
if (found) console.log(found.id, found.sftpUsername);
Define and validate your target data model.
MethodSignatureDescription
listlist()List schemas.
retrieveretrieve(id)Get a schema.
createcreate(params)Create a schema from a JSON Schema definition.
updateupdate(id, params)Update a schema’s definition.
removeremove(id)Delete a schema.
validatevalidate({ schemaId, data })Validate a payload against a schema.
Common workflows
  • Define the column structure as a JSON Schema definition
  • Validate a sample payload pre-ingestion
const schema = await filefeed.schemas.create({
  name: 'Employees',
  definition: {
    type: 'object',
    properties: {
      email: { type: 'string' },
      name: { type: 'string' },
    },
    required: ['email', 'name'],
  },
});
const result = await filefeed.schemas.validate({ schemaId: schema.id, data: { email: 'a@b.com', name: 'Ada' } });
Connect clients to schemas and define mappings/transforms. Field mappings support sourced entries ({ source, target, transform? }), static values ({ target, value }) that write a fixed constant into a column on every row, and aggregated entries ({ sources, target, delimiter? }) that join several input columns into one target — limited availability, see field-mapping kinds.
MethodSignatureDescription
listlist({ clientId?, connectionName? })List pipelines.
retrieveretrieve(id)Get a pipeline.
createcreate(params)Create a pipeline (mappings/transforms).
updateupdate(id, params)Update pipeline configuration.
removeremove(id)Delete a pipeline.
toggleActivetoggleActive(id)Enable/disable a pipeline.
Common workflows
  • Create a pipeline for a client + schema
  • Adjust mappings, then toggle active for go-live
const pipeline = await filefeed.pipelines.create({
  name: 'Employees',
  clientId,
  schemaId,
  mappings: {
    fieldMappings: [
      { source: 'emp_id', target: 'id' },
      { target: 'source_system', value: 'FileFeed' }, // static constant on every row
    ],
  },
});
await filefeed.pipelines.toggleActive(pipeline.id);
Manage processing jobs and retrieve processed data.
MethodSignatureDescription
listlist({ status?, clientId?, pipelineId?, pipelineName?, page?, limit? })Paginated runs. Filter by status/client/pipeline/ids.
retrieveretrieve(id)Get a single pipeline run.
getDatagetData({ pipelineRunId, offset?, limit? })Paginated processed rows (offset-based, up to 1000 per page).
ackack({ pipelineRunId })Mark run as processed (idempotent).
reprocessreprocess({ pipelineRunId })Re-run processing for a given run.
getOriginalFileUrlgetOriginalFileUrl({ pipelineRunId, expiresIn? })Presigned URL to the original file.
getProcessedFileUrlgetProcessedFileUrl({ pipelineRunId, expiresIn? })Presigned URL to the processed file.
deltadelta({ baseRunId, compareRunId, offset?, limit? })Compare two runs of the same pipeline; returns the records added/removed between their processed files, with summary counts and a paginated changes list.
Common workflows
  • Fetch completed runs, paginate data, then acknowledge the run
  • Download original or processed file for audit trails
  • Reprocess failed runs after fixing mapping or schema
  • Diff two runs of the same pipeline (e.g. yesterday vs today) to see which records changed
// Quick example
const runs = await filefeed.pipelineRuns.list({ status: 'completed', limit: 25 });
const page = await filefeed.pipelineRuns.getData({ pipelineRunId: runs.data[0].id, limit: 1000 });

// Compare the two most recent runs of the same pipeline
const diff = await filefeed.pipelineRuns.delta({
  baseRunId: runs.data[1].id,
  compareRunId: runs.data[0].id,
});
console.log(diff.summary); // { baseCount, compareCount, addedCount, removedCount }
Receive signed notifications for pipeline events.
MethodSignatureDescription
listlist()List webhooks.
retrieveretrieve(id)Get a webhook.
createcreate(params)Create a webhook (name, URL, optional headers). eventType defaults to GENERAL and secret is server-generated.
updateupdate(id, params)Update webhook configuration.
removeremove(id)Delete a webhook.
listDeliverieslistDeliveries(params)Inspect delivery attempts and status codes.
subscribeZapierPipelineRunEvents({ targetUrl })Subscribe a Zapier URL to pipeline-run events.
unsubscribeZapierPipelineRunEvents({ id })Remove a Zapier pipeline-run subscription.
Common workflows
  • Create a webhook for pipeline events
  • Monitor delivery health and retry on failure
const hook = await filefeed.webhooks.create({ name: 'Pipeline events', url: 'https://example.com/webhooks/filefeed' });
const deliveries = await filefeed.webhooks.listDeliveries({ webhookId: hook.id, page: 1, limit: 50 });
Push JSON data into outbound pipelines via multipart uploads.
MethodSignatureDescription
initUploadinitUpload(params)Create an upload session.
uploadPartuploadPart(uploadId, partNumber, params)Upload one JSON array part.
completeUploadcompleteUpload(uploadId, params)Finalize and trigger processing.
abortUploadabortUpload(uploadId)Cancel and cleanup parts.
getUploadStatusgetUploadStatus(uploadId)Check session progress.
uploadJsonuploadJson(params)Convenience: chunk, upload, and complete in one call.
Common workflows
  • Push data from your backend into a pipeline
  • Chunk large datasets and upload in parts
  • Use uploadJson() for simple one-shot uploads
  • Choose the delivered file’s name and format (csv | json | xml)
Pass the connection’s human-readable name as connectionName (the legacy clientName resolves by that same name and is deprecated).
const result = await filefeed.outbound.uploadJson({
  connectionName: 'Acme Corp',
  pipelineName: 'employee-sync',
  data: [{ remoteId: 'E001', firstName: 'Alice', lastName: 'Smith' }],
  outputFilename: 'employees.csv', // optional exact name
  outputFormat: 'csv',             // optional: csv | json | xml
});
See the Outbound Flow guide for the full walkthrough.
Browse and manage a connection’s file store (S3 drive). Paths are relative to the connection root; pipeline-backed folders are protected.
MethodSignatureDescription
browsebrowse({ connectionId, path?, token? })List one page of folders/files.
getMetadatagetMetadata({ connectionId, path })File size, content type, etag.
getDownloadUrlgetDownloadUrl({ connectionId, path })Presigned download URL.
createUploadTicketcreateUploadTicket(params)Presigned single/multipart upload.
completeUpload / abortUpload(params)Finalize / cancel a multipart upload.
createFolder / move / rename(params)Folder + path operations.
deleteObject / deleteFolder / bulkDelete(params)Delete (force = admin only).
const page = await filefeed.documents.browse({ connectionId: 'conn_1' });
console.log(page.folders, page.files);
Direct access to processed file content (distinct from per-run access on pipelineRuns).
MethodSignatureDescription
getJsongetJson({ clientName, fileName, pipelineId, offset?, limit? })Fetch a processed JSON file by name.
searchsearch({ pipelineRunIds, searchTerm?, ... })Search rows across processed files.
const results = await filefeed.files.search({
  pipelineRunIds: ['run_1', 'run_2'],
  searchTerm: 'john@example.com',
});
Per-connection notification preferences — deliver pipeline-run alerts over EMAIL / SLACK / SMS.
MethodSignatureDescription
getPreferencesgetPreferences(connectionId)List a connection’s preferences.
setPreferencessetPreferences(connectionId, { preferences })Upsert preferences (an enabled one needs recipients).
await filefeed.notifications.setPreferences('conn_123', {
  preferences: [
    { eventType: 'PIPELINE_RUN_FAILED', channel: 'EMAIL', isEnabled: true, recipients: ['ops@acme.com'] },
  ],
});
The documents, files, and notifications resources and the Zapier webhook methods require @filefeed/sdk ≥ 2.5.0.

Example: Paginate Data

const runs = await filefeed.pipelineRuns.list({ status: 'completed', limit: 50 });
for (const run of runs.data) {
  let offset: number | null = 0;
  do {
    const page = await filefeed.pipelineRuns.getData({ pipelineRunId: run.id, limit: 1000, offset });
    // process page.data
    offset = page.data.length === 1000 ? (offset ?? 0) + page.data.length : null;
  } while (offset !== null);
}