ObjectStackObjectStack

Export schema — API Protocol reference

Defines the export file formats, import validation, template-based field mapping, and the asynchronous import-job contracts.

Data Export & Import Protocol

Defines the export file formats, import validation, template-based field mapping, and the asynchronous import-job contracts.

Industry alignment: Salesforce Data Export, Airtable CSV Export, Dynamics 365 Data Management.

The export the platform serves is the synchronous streaming door GET /api/v1/data/:object/export, which answers the file itself as CSV, JSON or XLSX. The asynchronous export-job API that used to be declared here (export jobs, their progress / download / list shapes, scheduled exports and ExportApiContracts) was never served by any route and was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove); a recurring export is a Job whose handler you write.

Source: packages/spec/src/api/export.zod.ts

TypeScript Usage

import { CreateImportJobRequestSchema, CreateImportJobResponseSchema, DeduplicationStrategy, ExportFormat, ExportImportTemplateSchema, FieldMappingEntrySchema, ImportJobProgressSchema, ImportJobResultsSchema, ImportJobStatus, ImportJobSummarySchema, ImportMappingSchema, ImportRequestSchema, ImportResponseSchema, ImportRowResultSchema, ImportValidationConfigSchema, ImportValidationMode, ImportValidationResultSchema, ImportWriteMode, ListImportJobsRequestSchema, ListImportJobsResponseSchema, UndoImportJobResponseSchema } from '@objectstack/spec/api';
import type { CreateImportJobRequest, CreateImportJobResponse, DeduplicationStrategy, ExportFormat, ExportImportTemplate, FieldMappingEntry, ImportJobProgress, ImportJobResults, ImportJobStatus, ImportJobSummary, ImportMapping, ImportRequest, ImportResponse, ImportRowResult, ImportValidationConfig, ImportValidationMode, ImportValidationResult, ImportWriteMode, ListImportJobsRequest, ListImportJobsResponse, UndoImportJobResponse } from '@objectstack/spec/api';

// Validate data
const result = CreateImportJobRequestSchema.parse(data);

CreateImportJobRequest

Properties

PropertyTypeRequiredDescription
formatEnum<'csv' | 'json' | 'xlsx'>optionalPayload shape: csv text, a rows[] array, or a base64 xlsx (inferred when omitted)
csvstringoptionalCSV text (when format = csv)
rowsRecord<string, any>[]optionalRow objects (when format = json)
xlsxBase64stringoptionalBase64-encoded .xlsx workbook bytes (when format = xlsx); parsed server-side
sheetstring | integeroptionalWorksheet name or 1-based index to read (xlsx; defaults to the first sheet)
mappingRecord<string, string> | { sourceField: string; targetField: string; targetLabel?: string; transform?: Enum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>; … }[]optionalSource column → target field mapping
mappingNamestringoptionalName of a registered mapping metadata artifact to apply; the server resolves it (org-scoped rows first, then env-wide) and projects columns through it. Mutually exclusive with an inline mapping — supplying both is refused (400 CONFLICTING_MAPPING).
dryRunbooleanoptional (default: false)Validate + coerce every row without persisting. The verdict is the engine's own write-path validation, with one boundary an author should know: a preview runs NO automations. Hooks never fire in a dry run — a preview that executed user-authored side effects (mail, outbound calls, writes to other objects) would be the retired validateOnly defect in a new spelling. So a dry run with runAutomations: true can report required for a field a beforeInsert hook would populate during the real import; for hook-derived fields the real write is authoritative.
writeModeEnum<'insert' | 'update' | 'upsert'>optional (default: "insert")insert / update / upsert semantics
matchFieldsstring[]optionalFields that identify an existing record (required for update/upsert)
runAutomationsbooleanoptional (default: true)Fire triggers/hooks for each imported row. ON by default, and opting out must be explicit: automations always ran on import historically (the engine ignored this flag until this flag was honoured), so a caller that wants a silent bulk load sends runAutomations: false — omitting the key runs them. This matches platform convention (Salesforce fires triggers on import by default). One boundary: a dryRun preview runs NO automations whatever this flag says.
treatAsHistoricalbooleanoptional (default: false)Import as established historical facts. Two effects, both off by default so a normal import is unchanged: (1) skip the state_machine rule so mid-lifecycle rows (e.g. already-closed tickets, closed_won deals) are not rejected by initialStates; and (2) preserve the original audit timeline — keep the supplied created_at / updated_at / updated_by and author-declared business readonly fields (e.g. closed_at, resolved_by) instead of stamping-now / stripping them. Undoing a historical import mirrors (2): the captured pre-import values are restored verbatim rather than re-stamped.
trimWhitespacebooleanoptional (default: true)Trim leading/trailing whitespace from string cells
nullValuesstring[]optionalStrings treated as null/blank (besides empty string)
createMissingOptionsbooleanoptional (default: false)Keep a select / radio / multiselect cell that matches none of the field's options instead of failing the row. The cell is stored as written (trimmed; for a multi-value cell, each unmatched item), and the engine's option check admits exactly the values this import kept, on this import's writes (dry run included). The field's option list is not changed: a later write that sends the field is judged against the options again, while one that leaves the field out is not affected. A field bound to a shared picklist that did not resolve is still refused.
skipBlankMatchKeybooleanoptional (default: false)Skip rows whose matchFields are blank (default: upsert creates them, update skips them)

Nested Shape: CreateImportJobRequest.mapping[number]

PropertyTypeRequiredDescription
sourceFieldstring✅Field name in the source data (import) or object (export)
targetFieldstring✅Field name in the target object (import) or file column (export)
targetLabelstringoptionalDisplay label for the target column (export)
transformEnum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>optional (default: "none")Transformation to apply during mapping
defaultValueanyoptionalDefault value if source field is null/empty
requiredbooleanoptional (default: false)Whether this field is required (import validation)

CreateImportJobResponse

Properties

PropertyTypeRequiredDescription
jobIdstring✅Import job id — poll progress/results with this
objectstring✅Target object name
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>✅Initial job status (usually "pending")
totalinteger✅Rows accepted for processing
createdAtstring✅Job creation timestamp (ISO 8601)

DeduplicationStrategy

Allowed Values

  • skip
  • update
  • create_new
  • fail

ExportFormat

Allowed Values

  • csv
  • json
  • jsonl
  • xlsx
  • parquet

ExportImportTemplate

Properties

PropertyTypeRequiredDescription
idstringoptionalTemplate ID (generated on save)
namestring✅Template machine name (snake_case)
labelstring✅Human-readable template label
descriptionstringoptionalTemplate description
objectstring✅Target object name
directionEnum<'import' | 'export' | 'bidirectional'>✅Template direction
formatEnum<'csv' | 'json' | 'jsonl' | 'xlsx' | 'parquet'>optionalDefault file format for this template
mappings{ sourceField: string; targetField: string; targetLabel?: string; transform?: Enum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>; … }[]✅Field mapping entries
createdAtstringoptionalTemplate creation timestamp
updatedAtstringoptionalLast update timestamp
createdBystringoptionalUser who created the template

Nested Shape: ExportImportTemplate.mappings[number]

PropertyTypeRequiredDescription
sourceFieldstring✅Field name in the source data (import) or object (export)
targetFieldstring✅Field name in the target object (import) or file column (export)
targetLabelstringoptionalDisplay label for the target column (export)
transformEnum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>optional (default: "none")Transformation to apply during mapping
defaultValueanyoptionalDefault value if source field is null/empty
requiredbooleanoptional (default: false)Whether this field is required (import validation)

FieldMappingEntry

Properties

PropertyTypeRequiredDescription
sourceFieldstring✅Field name in the source data (import) or object (export)
targetFieldstring✅Field name in the target object (import) or file column (export)
targetLabelstringoptionalDisplay label for the target column (export)
transformEnum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>optional (default: "none")Transformation to apply during mapping
defaultValueanyoptionalDefault value if source field is null/empty
requiredbooleanoptional (default: false)Whether this field is required (import validation)

ImportJobProgress

Properties

PropertyTypeRequiredDescription
jobIdstring✅Import job id
objectstring✅Target object name
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>✅Current job status
dryRunboolean✅Whether this is a validate-only pass
writeModeEnum<'insert' | 'update' | 'upsert'>✅Write mode used
totalinteger✅Total rows to process
processedinteger✅Rows processed so far
createdinteger✅Rows that created a new record
updatedinteger✅Rows that updated an existing record
skippedinteger✅Rows skipped
errorsinteger✅Rows that failed
percentCompletenumber✅processed / total as a percentage
undoableboolean✅Whether this job can still be logically rolled back (undo log captured, terminal state, not yet reverted)
revertedAtstringoptionalWhen the job was undone / rolled back (ISO 8601)
errorstringoptionalFatal error message (when status = failed)
startedAtstringoptionalProcessing start timestamp (ISO 8601)
completedAtstringoptionalCompletion timestamp (ISO 8601)
createdAtstring✅Job creation timestamp (ISO 8601)

ImportJobResults

Properties

PropertyTypeRequiredDescription
jobIdstring✅Import job id
objectstring✅Target object name
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>✅Current job status
dryRunboolean✅Whether this is a validate-only pass
writeModeEnum<'insert' | 'update' | 'upsert'>✅Write mode used
totalinteger✅Total rows to process
processedinteger✅Rows processed so far
createdinteger✅Rows that created a new record
updatedinteger✅Rows that updated an existing record
skippedinteger✅Rows skipped
errorsinteger✅Rows that failed
percentCompletenumber✅processed / total as a percentage
undoableboolean✅Whether this job can still be logically rolled back (undo log captured, terminal state, not yet reverted)
revertedAtstringoptionalWhen the job was undone / rolled back (ISO 8601)
errorstringoptionalFatal error message (when status = failed)
startedAtstringoptionalProcessing start timestamp (ISO 8601)
completedAtstringoptionalCompletion timestamp (ISO 8601)
createdAtstring✅Job creation timestamp (ISO 8601)
results{ row: integer; ok: boolean; action: Enum<'created' | 'updated' | 'skipped' | 'failed'>; id?: string; … }[]✅Capped sample of per-row outcomes, failures first. An ok row, and any droppedFields or warnings it carries, reaches this reader only if it falls inside the sample; resultsTruncated says whether the sample is partial, and the job counters count every row.
resultsTruncatedboolean✅Whether results is a capped sample of a larger set

Nested Shape: ImportJobResults.results[number]

PropertyTypeRequiredDescription
rowinteger✅1-based row number in the source data
okboolean✅Whether the row succeeded
actionEnum<'created' | 'updated' | 'skipped' | 'failed'>✅What happened to the row
idstringoptionalRecord id (created/updated rows)
fieldstringoptionalField that caused a coercion/validation error
codestringoptionalError code (failed rows)
errorstringoptionalHuman-readable error message (failed rows)
warnings{ field: string; code: string; message: string }[]optionalFindings this deployment ADMITS rather than rejects (ADR-0104 value shapes under a warn-first posture), in the same { field, code, message } shape the validate verdict carries. Set only on a dry-run row the verdict accepted: the row is ok because the write would store it and log the same complaint. A committed row never carries it, since the write path has no channel to report admitted findings on.
droppedFields{ object: string; fields: string[]; reason: Enum<'readonly' | 'readonly_when' | 'primary_key' | 'computed'> }[]optionalWrite-observability: caller-supplied fields the engine LEGALLY strips from THIS row, one event per reason, in the engine's own droppedFields shape and reason vocabulary. A committed row reports the strips its write made. A dry-run row reports the strips its preview runs, which for a row the import would update excludes readonlyWhen and primary-key strips, so that row can name fewer fields than its commit. The row still succeeds: ok and action are unchanged. Present only when at least one field was dropped. A server or write path that does not produce this report omits the key too, so an absent key alone does not prove nothing was dropped. In an async job's results, an ok row's drops reach the reader only if the row falls inside that capped, failures-first sample.

ImportJobStatus

Allowed Values

  • pending
  • running
  • succeeded
  • failed
  • cancelled

ImportJobSummary

Properties

PropertyTypeRequiredDescription
jobIdstring✅Import job id
objectstring✅Target object name
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>✅Job status
totalinteger✅Total rows
processedinteger✅Rows processed
createdinteger✅Rows created
updatedinteger✅Rows updated
skippedinteger✅Rows skipped
errorsinteger✅Rows failed
createdAtstring✅Job creation timestamp (ISO 8601)
completedAtstringoptionalCompletion timestamp (ISO 8601)
undoableboolean✅Whether this job can still be logically rolled back
revertedAtstringoptionalWhen the job was undone / rolled back (ISO 8601)

ImportMapping

Union Options

This schema accepts one of the following structures:

Option 1

Type: Record<string, string>


Option 2

Type: { sourceField: string; targetField: string; targetLabel?: string; transform?: Enum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>; … }[]



ImportRequest

Properties

PropertyTypeRequiredDescription
formatEnum<'csv' | 'json' | 'xlsx'>optionalPayload shape: csv text, a rows[] array, or a base64 xlsx (inferred when omitted)
csvstringoptionalCSV text (when format = csv)
rowsRecord<string, any>[]optionalRow objects (when format = json)
xlsxBase64stringoptionalBase64-encoded .xlsx workbook bytes (when format = xlsx); parsed server-side
sheetstring | integeroptionalWorksheet name or 1-based index to read (xlsx; defaults to the first sheet)
mappingRecord<string, string> | { sourceField: string; targetField: string; targetLabel?: string; transform?: Enum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>; … }[]optionalSource column → target field mapping
mappingNamestringoptionalName of a registered mapping metadata artifact to apply; the server resolves it (org-scoped rows first, then env-wide) and projects columns through it. Mutually exclusive with an inline mapping — supplying both is refused (400 CONFLICTING_MAPPING).
dryRunbooleanoptional (default: false)Validate + coerce every row without persisting. The verdict is the engine's own write-path validation, with one boundary an author should know: a preview runs NO automations. Hooks never fire in a dry run — a preview that executed user-authored side effects (mail, outbound calls, writes to other objects) would be the retired validateOnly defect in a new spelling. So a dry run with runAutomations: true can report required for a field a beforeInsert hook would populate during the real import; for hook-derived fields the real write is authoritative.
writeModeEnum<'insert' | 'update' | 'upsert'>optional (default: "insert")insert / update / upsert semantics
matchFieldsstring[]optionalFields that identify an existing record (required for update/upsert)
runAutomationsbooleanoptional (default: true)Fire triggers/hooks for each imported row. ON by default, and opting out must be explicit: automations always ran on import historically (the engine ignored this flag until this flag was honoured), so a caller that wants a silent bulk load sends runAutomations: false — omitting the key runs them. This matches platform convention (Salesforce fires triggers on import by default). One boundary: a dryRun preview runs NO automations whatever this flag says.
treatAsHistoricalbooleanoptional (default: false)Import as established historical facts. Two effects, both off by default so a normal import is unchanged: (1) skip the state_machine rule so mid-lifecycle rows (e.g. already-closed tickets, closed_won deals) are not rejected by initialStates; and (2) preserve the original audit timeline — keep the supplied created_at / updated_at / updated_by and author-declared business readonly fields (e.g. closed_at, resolved_by) instead of stamping-now / stripping them. Undoing a historical import mirrors (2): the captured pre-import values are restored verbatim rather than re-stamped.
trimWhitespacebooleanoptional (default: true)Trim leading/trailing whitespace from string cells
nullValuesstring[]optionalStrings treated as null/blank (besides empty string)
createMissingOptionsbooleanoptional (default: false)Keep a select / radio / multiselect cell that matches none of the field's options instead of failing the row. The cell is stored as written (trimmed; for a multi-value cell, each unmatched item), and the engine's option check admits exactly the values this import kept, on this import's writes (dry run included). The field's option list is not changed: a later write that sends the field is judged against the options again, while one that leaves the field out is not affected. A field bound to a shared picklist that did not resolve is still refused.
skipBlankMatchKeybooleanoptional (default: false)Skip rows whose matchFields are blank (default: upsert creates them, update skips them)

Nested Shape: ImportRequest.mapping[number]

PropertyTypeRequiredDescription
sourceFieldstring✅Field name in the source data (import) or object (export)
targetFieldstring✅Field name in the target object (import) or file column (export)
targetLabelstringoptionalDisplay label for the target column (export)
transformEnum<'none' | 'uppercase' | 'lowercase' | 'trim' | 'date_format' | 'lookup'>optional (default: "none")Transformation to apply during mapping
defaultValueanyoptionalDefault value if source field is null/empty
requiredbooleanoptional (default: false)Whether this field is required (import validation)

ImportResponse

Properties

PropertyTypeRequiredDescription
objectstring✅Target object name
dryRunboolean✅Whether this was a validate-only pass
writeModeEnum<'insert' | 'update' | 'upsert'>✅Write mode used
totalinteger✅Rows processed
okinteger✅Rows that succeeded
errorsinteger✅Rows that failed
createdinteger✅Rows that created a new record
updatedinteger✅Rows that updated an existing record
skippedinteger✅Rows skipped (no match in update mode, etc.)
results{ row: integer; ok: boolean; action: Enum<'created' | 'updated' | 'skipped' | 'failed'>; id?: string; … }[]✅Per-row outcomes

Nested Shape: ImportResponse.results[number]

PropertyTypeRequiredDescription
rowinteger✅1-based row number in the source data
okboolean✅Whether the row succeeded
actionEnum<'created' | 'updated' | 'skipped' | 'failed'>✅What happened to the row
idstringoptionalRecord id (created/updated rows)
fieldstringoptionalField that caused a coercion/validation error
codestringoptionalError code (failed rows)
errorstringoptionalHuman-readable error message (failed rows)
warnings{ field: string; code: string; message: string }[]optionalFindings this deployment ADMITS rather than rejects (ADR-0104 value shapes under a warn-first posture), in the same { field, code, message } shape the validate verdict carries. Set only on a dry-run row the verdict accepted: the row is ok because the write would store it and log the same complaint. A committed row never carries it, since the write path has no channel to report admitted findings on.
droppedFields{ object: string; fields: string[]; reason: Enum<'readonly' | 'readonly_when' | 'primary_key' | 'computed'> }[]optionalWrite-observability: caller-supplied fields the engine LEGALLY strips from THIS row, one event per reason, in the engine's own droppedFields shape and reason vocabulary. A committed row reports the strips its write made. A dry-run row reports the strips its preview runs, which for a row the import would update excludes readonlyWhen and primary-key strips, so that row can name fewer fields than its commit. The row still succeeds: ok and action are unchanged. Present only when at least one field was dropped. A server or write path that does not produce this report omits the key too, so an absent key alone does not prove nothing was dropped. In an async job's results, an ok row's drops reach the reader only if the row falls inside that capped, failures-first sample.

ImportRowResult

Properties

PropertyTypeRequiredDescription
rowinteger✅1-based row number in the source data
okboolean✅Whether the row succeeded
actionEnum<'created' | 'updated' | 'skipped' | 'failed'>✅What happened to the row
idstringoptionalRecord id (created/updated rows)
fieldstringoptionalField that caused a coercion/validation error
codestringoptionalError code (failed rows)
errorstringoptionalHuman-readable error message (failed rows)
warnings{ field: string; code: string; message: string }[]optionalFindings this deployment ADMITS rather than rejects (ADR-0104 value shapes under a warn-first posture), in the same { field, code, message } shape the validate verdict carries. Set only on a dry-run row the verdict accepted: the row is ok because the write would store it and log the same complaint. A committed row never carries it, since the write path has no channel to report admitted findings on.
droppedFields{ object: string; fields: string[]; reason: Enum<'readonly' | 'readonly_when' | 'primary_key' | 'computed'> }[]optionalWrite-observability: caller-supplied fields the engine LEGALLY strips from THIS row, one event per reason, in the engine's own droppedFields shape and reason vocabulary. A committed row reports the strips its write made. A dry-run row reports the strips its preview runs, which for a row the import would update excludes readonlyWhen and primary-key strips, so that row can name fewer fields than its commit. The row still succeeds: ok and action are unchanged. Present only when at least one field was dropped. A server or write path that does not produce this report omits the key too, so an absent key alone does not prove nothing was dropped. In an async job's results, an ok row's drops reach the reader only if the row falls inside that capped, failures-first sample.

Nested Shape: ImportRowResult.warnings[number]

PropertyTypeRequiredDescription
fieldstring✅The field the finding is about (_record for an object-level rule).
codestring✅Machine-readable finding code, e.g. required, invalid_type, rule_violation.
messagestring✅Human-readable message — a validation rule's author-written text where one exists.

Nested Shape: ImportRowResult.droppedFields[number]

A write-path strip event: caller-supplied fields legally dropped from the payload

PropertyTypeRequiredDescription
objectstring✅Object the write targeted (resolved object name)
fieldsstring[]✅Caller-supplied field names the engine removed from the write payload
reasonEnum<'readonly' | 'readonly_when' | 'primary_key' | 'computed'>✅Why the fields were dropped: static readonly, a TRUE readonlyWhen predicate, the primary-key strip of a payload id the engine ruled is not an identifier, or a computed (formula) field no driver has a column for

ImportValidationConfig

Properties

PropertyTypeRequiredDescription
modeEnum<'strict' | 'lenient' | 'dry_run'>optional (default: "strict")Validation mode for the import
deduplication{ strategy?: Enum<'skip' | 'update' | 'create_new' | 'fail'>; matchFields: string[] }optionalDeduplication configuration
maxErrorsintegeroptional (default: 100)Maximum validation errors before aborting
trimWhitespacebooleanoptional (default: true)Trim leading/trailing whitespace from string fields
dateFormatstringoptionalExpected date format in import data (e.g., "YYYY-MM-DD")
nullValuesstring[]optionalStrings to treat as null (e.g., ["", "N/A", "null"])

Nested Shape: ImportValidationConfig.deduplication

PropertyTypeRequiredDescription
strategyEnum<'skip' | 'update' | 'create_new' | 'fail'>optional (default: "skip")How to handle duplicate records
matchFieldsstring[]✅Fields used to identify duplicates (e.g., "email", "external_id")

ImportValidationMode

Allowed Values

  • strict
  • lenient
  • dry_run

ImportValidationResult

Properties

PropertyTypeRequiredDescription
successboolean✅Operation success status
error{ code: Enum<'VALIDATION_ERROR' | 'INVALID_FIELD' | 'MISSING_REQUIRED_FIELD' | …>; declaredCode?: string; message: string; userMessage?: string; … }optionalError details if success is false
meta{ timestamp: string; duration?: integer; requestId?: string; traceId?: string }optionalResponse metadata
data{ totalRecords: integer; validRecords: integer; invalidRecords: integer; duplicateRecords: integer; … }✅

Nested Shape: ImportValidationResult.error

PropertyTypeRequiredDescription
codeEnum<'VALIDATION_ERROR' | 'INVALID_FIELD' | 'MISSING_REQUIRED_FIELD' | …>✅Error code (e.g. VALIDATION_ERROR; StandardErrorCode ∪ the ledger the serving side registers — ERROR_CODE_LEDGER for framework packages)
declaredCodestringoptionalThe producer-declared code, verbatim, when it is not a member of the closed code vocabulary — the open, author-authored channel (app-specific spellings; ADR-0112)
messagestring✅Readable error message
userMessagestringoptionalProducer-marked user-facing refusal text, verbatim. Present exactly when the producer opted in at throw time; consumers render it to end users and keep their generic substitution for anything unmarked. Status-agnostic; never replaces message.
refusaltrueoptionalProducer-declared: the 5xx this envelope carries is a deliberate refusal whose message is authored for the caller, so a boundary that reads the declaration keeps it verbatim (until the withhold arms read it, a declared refusal is still withheld). Absent (the default) on a declared fault, whose message is withheld from the body and logged for the operator; redundant on a 4xx. Presence is the declaration — true is the only value.
categorystringoptionalError category (e.g. validation, authorization)
httpStatusintegeroptionalHTTP status of the response carrying this error
detailsanyoptionalAdditional error context (e.g. field validation errors)
requestIdstringoptionalRequest ID for tracking

Nested Shape: ImportValidationResult.meta

PropertyTypeRequiredDescription
timestampstring✅
durationintegeroptionalServer-side processing duration in milliseconds
requestIdstringoptional
traceIdstringoptional

Nested Shape: ImportValidationResult.data

PropertyTypeRequiredDescription
totalRecordsinteger✅Total records in import file
validRecordsinteger✅Records that passed validation
invalidRecordsinteger✅Records that failed validation
duplicateRecordsinteger✅Duplicate records detected
errors{ row: integer; field?: string; code: string; message: string }[]✅List of validation errors
previewRecord<string, any>[]optionalPreview of first N valid records (for dry_run mode)

ImportWriteMode

Allowed Values

  • insert
  • update
  • upsert

ListImportJobsRequest

Properties

PropertyTypeRequiredDescription
objectstringoptionalFilter to one target object
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>optionalFilter by job status
limitintegeroptional (default: 50)Max rows to return
offsetintegeroptional (default: 0)Pagination offset

ListImportJobsResponse

Properties

PropertyTypeRequiredDescription
jobs{ jobId: string; object: string; status: Enum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>; total: integer; … }[]✅Import jobs, newest first

Nested Shape: ListImportJobsResponse.jobs[number]

PropertyTypeRequiredDescription
jobIdstring✅Import job id
objectstring✅Target object name
statusEnum<'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled'>✅Job status
totalinteger✅Total rows
processedinteger✅Rows processed
createdinteger✅Rows created
updatedinteger✅Rows updated
skippedinteger✅Rows skipped
errorsinteger✅Rows failed
createdAtstring✅Job creation timestamp (ISO 8601)
completedAtstringoptionalCompletion timestamp (ISO 8601)
undoableboolean✅Whether this job can still be logically rolled back
revertedAtstringoptionalWhen the job was undone / rolled back (ISO 8601)

UndoImportJobResponse

Properties

PropertyTypeRequiredDescription
successboolean✅Whether the undo completed
jobIdstring✅Import job id
objectstring✅Target object name
deletedinteger✅Created records deleted
restoredinteger✅Updated records restored to pre-import values
failedinteger✅Reversal operations that failed

On this page