Skip to content

API reference

Preview contact import

customers.PreviewContactImportReadAPI key

Prepare contacts from an uploaded CSV, TSV or vCard without saving records or making an AI call. Supply zero-based column mappings for a table. Review each row, check existing contacts, then use customers.CreatePerson or customers.UpdatePerson to import them with the usual permissions and retry guarantees. Names, email addresses, phone numbers, job titles and LinkedIn URLs are supported.

POST/v1/operations/customers.PreviewContactImport
On this page

Access & visibility

Allow customers.PreviewContactImport on your API key.

Workspace access by default. Private member data requires approved member delegation through Brigg-Act-As; the key supplies permissions while private ownership and project boundaries remain enforced.

Set up authentication · Choose permissions

Request fields

Send a JSON object with the following fields. Required fields must be included; omit optional fields you do not need.

file_idstringRequired

Use a file_id returned by this listing or by CompleteUpload. It is not an upload ID, storage path or filename. documents.ListDocuments.

At least 1 character.

has_headerbooleanOptional

Whether the uploaded table's first row contains column headings.

Default: true.

mappingobjectOptional

Mapping from supported Person fields to zero-based table column indexes.

Nested fields
display_nameintegerOptional

Full name shown for the contact.

Minimum: 0.

emailintegerOptional

Email address.

Minimum: 0.

phoneintegerOptional

Phone number including its country calling code.

Minimum: 0.

titleintegerOptional

Display title.

Minimum: 0.

linkedin_urlintegerOptional

Public LinkedIn profile URL for the person or company.

Minimum: 0.

limitintegerOptional

Maximum number of results to return in this page. Continue with next_cursor when returned.

Default: 50. Range: 1 to 100.

cursorstringOptional

Copy next_cursor from the preceding response. Keep the same filters, sort and credential.

Response

Returns 200 OK with a JSON body.

An empty items array means this page contains no matching visible results. Follow next_cursor when present.

file_idstringRequired

File identifier.

row_countintegerRequired

Number of source rows detected in the uploaded file.

duplicate_countintegerRequired

Number of source rows classified as duplicates.

invalid_countintegerRequired

Number of source rows that did not pass the contact-field checks.

itemsarray of Contact import rowRequired

Parsed rows from the uploaded file, with validation and duplicate results. Pass next_cursor as cursor to continue when a next cursor is returned.

Item fields
rowintegerRequired

One-based row number in the source file.

statusstringRequired

Preparation result for this row. Review invalid and duplicate rows before importing.

Allowed: "ready", "duplicate", "invalid".

dataobjectOptional

Contact fields parsed using the supplied column mapping.

Nested fields
display_namestringOptional

Full name shown for the contact.

emailstringOptional

Email address.

phonestringOptional

Phone number including its country calling code.

titlestringOptional

Display title.

linkedin_urlstringOptional

Public LinkedIn profile URL for the person or company.

errorstringOptional

Explanation of a row validation failure, when present.

next_cursorstring or nullRequired

Pass this value as cursor to continue with the same filters, sort and credential. Null when there are no more results.

has_morebooleanRequired

Whether another page of results is available.

Pagination

Pass next_cursor as cursor on the next request, keeping the same query and acting identity. Stop when next_cursor is null. Treat the cursor as opaque; never construct or edit it.

const query = {
  "file_id": "f_contacts",
  "has_header": true,
  "mapping": {
    "display_name": 0,
    "email": 1,
    "title": 2
  },
  "limit": 50
};
let cursor;
do {
  const response = await fetch("https://api.brigg.app/v1/operations/customers.PreviewContactImport", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.BRIGG_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ...query, ...(cursor ? { cursor } : {}) }),
  });
  const page = await response.json();
  if (!response.ok) throw new Error(`${response.status}: ${page.message}`);
  for (const item of page.items) {
    console.log(item); // Process or upsert each result.
  }
  cursor = page.next_cursor;
} while (cursor);

Errors & retries

This operation reads data. It needs no idempotency key and can be retried after a transient failure.

For rate limits, follow the server’s retry guidance and back off. See HTTP errors and safe retries and limits.

HTTP status Code What to do
400 invalid_json Send a JSON object with Content-Type: application/json.
400 invalid_input Check the request fields and types.
401 invalid_key The workspace API key is missing, invalid or revoked.
403 forbidden Check the key’s operation and resource grants. If Brigg-Act-As is supplied, the key must be authorized to delegate to that member.
404 not_found The requested operation or resource is not available to this credential.
429 rate_limited Wait for Retry-After before retrying.
422 text_file_required Upload a text file containing CSV, TSV or vCard data.
422 invalid_text_encoding Upload UTF-8 text.
413 source_too_large Contact preparation supports the existing 4,000,000-character text-file limit; no rows are truncated.

Next steps

Download OpenAPI · Versioning & retirement

JSON schemas

Use the complete schemas for validation or client generation.

Full request JSON schema
{
  "type": "object",
  "properties": {
    "file_id": {
      "type": "string",
      "minLength": 1,
      "description": "Use a file_id returned by this listing or by CompleteUpload. It is not an upload ID, storage path or filename. [documents.ListDocuments](/developers/reference/documents/ListDocuments)."
    },
    "has_header": {
      "type": "boolean",
      "default": true,
      "description": "Whether the uploaded table's first row contains column headings."
    },
    "mapping": {
      "type": "object",
      "properties": {
        "display_name": {
          "type": "integer",
          "minimum": 0,
          "description": "Full name shown for the contact."
        },
        "email": {
          "type": "integer",
          "minimum": 0,
          "description": "Email address."
        },
        "phone": {
          "type": "integer",
          "minimum": 0,
          "description": "Phone number including its country calling code."
        },
        "title": {
          "type": "integer",
          "minimum": 0,
          "description": "Display title."
        },
        "linkedin_url": {
          "type": "integer",
          "minimum": 0,
          "description": "Public LinkedIn profile URL for the person or company."
        }
      },
      "additionalProperties": false,
      "description": "Mapping from supported Person fields to zero-based table column indexes."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 50,
      "description": "Maximum number of results to return in this page. Continue with next_cursor when returned."
    },
    "cursor": {
      "type": "string",
      "description": "Copy next_cursor from the preceding response. Keep the same filters, sort and credential."
    }
  },
  "required": [
    "file_id"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "file_id": "f_contacts",
      "has_header": true,
      "mapping": {
        "display_name": 0,
        "email": 1,
        "title": 2
      },
      "limit": 50
    }
  ]
}
Full response JSON schema
{
  "type": "object",
  "properties": {
    "file_id": {
      "type": "string",
      "description": "File identifier."
    },
    "row_count": {
      "type": "integer",
      "description": "Number of source rows detected in the uploaded file."
    },
    "duplicate_count": {
      "type": "integer",
      "description": "Number of source rows classified as duplicates."
    },
    "invalid_count": {
      "type": "integer",
      "description": "Number of source rows that did not pass the contact-field checks."
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "row": {
            "type": "integer",
            "description": "One-based row number in the source file."
          },
          "status": {
            "type": "string",
            "enum": [
              "ready",
              "duplicate",
              "invalid"
            ],
            "description": "Preparation result for this row. Review invalid and duplicate rows before importing."
          },
          "data": {
            "type": "object",
            "properties": {
              "display_name": {
                "type": "string",
                "description": "Full name shown for the contact."
              },
              "email": {
                "type": "string",
                "description": "Email address."
              },
              "phone": {
                "type": "string",
                "description": "Phone number including its country calling code."
              },
              "title": {
                "type": "string",
                "description": "Display title."
              },
              "linkedin_url": {
                "type": "string",
                "description": "Public LinkedIn profile URL for the person or company."
              }
            },
            "additionalProperties": false,
            "description": "Contact fields parsed using the supplied column mapping."
          },
          "error": {
            "type": "string",
            "description": "Explanation of a row validation failure, when present."
          }
        },
        "required": [
          "row",
          "status"
        ],
        "additionalProperties": false,
        "title": "Contact import row"
      },
      "description": "Parsed rows from the uploaded file, with validation and duplicate results. Pass next_cursor as cursor to continue when a next cursor is returned."
    },
    "next_cursor": {
      "type": [
        "string",
        "null"
      ],
      "description": "Pass this value as cursor to continue with the same filters, sort and credential. Null when there are no more results."
    },
    "has_more": {
      "type": "boolean",
      "description": "Whether another page of results is available."
    }
  },
  "required": [
    "file_id",
    "row_count",
    "duplicate_count",
    "invalid_count",
    "items",
    "next_cursor",
    "has_more"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "file_id": "f_contacts",
      "row_count": 1,
      "duplicate_count": 0,
      "invalid_count": 0,
      "items": [
        {
          "row": 1,
          "status": "ready",
          "data": {
            "display_name": "Alex Morgan",
            "email": "alex@example.com",
            "title": "Operations manager"
          }
        }
      ],
      "has_more": false,
      "next_cursor": null
    }
  ]
}

Search by operation name or what you want to build.

Use arrow keys to browse. Enter opens a result.