CSVJetty

Docs

Home
Dashboard

Receive data

Callbacks

Receive data

Callback delivery

Receive validated CSV records directly in your application with CSVJetty onData callback delivery, including row-level error handling and idempotency.

View as Markdown

On this page

onDataSave recordsReject individual recordsImport payloadCompletion events

Callback delivery keeps imported row data in the browser and hands it directly to your application's onData function. Your app decides where and how to save it.

onData

Callback delivery

<CSVJetty  importerKey="YOUR_IMPORTER_KEY"  onData={async ({ rows, importId, rowNumbers }) => {    console.log(rows);  }}>  Import contacts</CSVJetty>

For callback delivery, onData is required. CSVJetty waits for the returned promise before completing that delivery step. Throw an error when your application could not save the batch. If you are choosing between callbacks and webhooks, see Delivery modes.

Save records through your API

Keep database credentials and authorization logic on your server. Forward the callback payload to an authenticated endpoint owned by your application.

Production callback

<CSVJetty  importerKey="YOUR_IMPORTER_KEY"  onData={async ({ rows, importId, rowNumbers }) => {    const response = await fetch("/api/contacts/import", {      method: "POST",      headers: { "Content-Type": "application/json" },      body: JSON.stringify({ rows, importId, rowNumbers }),    });
    if (!response.ok) {      throw new Error("Could not save contacts.");    }
    const body = await response.text();    return body ? JSON.parse(body) : undefined;  }}>  Import contacts</CSVJetty>

Validate twice

CSVJetty validation is designed for a good import experience. Your server should independently validate authorization, uniqueness, foreign keys, and any business rules required before writing data.

Reject individual records

Return an errors array to reject specific original CSV rows while allowing the rest of the batch to succeed.

JS

return {  errors: [    {      row: 2,      message: "Email already exists",    },  ],};

Row numbers start at 1 after the CSV header and retain their original values even when invalid rows have been filtered out.

Import payload

JS

{  importId: "IMPORT_ID",  fileName: "contacts.csv",  rows: [    {      name: "Ada",      email: "ada@example.com",    },  ],  rowNumbers: [1],  skippedRows: 0,  uploadedFileHeaders: ["Full Name", "Email"],  matchedColumnsMap: {    name: "Full Name",    email: "Email",  },}

If Include All Unmatched Columns in Import is enabled, each delivered record also includes an _unmatched object containing unmatched source columns. See the full Import payload reference.

Completion events

Use onComplete for UI updates after the importer finishes. It receives{ importId, accepted, rejected }. Use onClose when you need to react to the importer modal closing.