Importing Data
The Import API allows you to bulk import data from CSV files into Terros. Imports are asynchronous — you initiate an import, upload a file, then poll for status until processing completes.
Supported Entity Types
You can import the following entity types:
Account— customer accountsContact— contacts associated with accountsCalendarEvent— calendar eventsUser— users in your organizationTask— tasks assigned to usersRecruit— recruit records
Import Flow
Importing data is a three-step process:
Step 1: Initiate the Import
Call Add Import to create an import job. The response includes a pre-signed S3 URL for uploading your CSV file.
curl -X POST "https://api.terros.com/import/add" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey $TERROS_API_KEY" \
-d '{
"entity": "Account",
"name": "Q1 Account Import"
}'
Response:
{
"type": "success",
"url": "https://s3.amazonaws.com/terros-imports/imports/Import:abc123/upload.csv?X-Amz-Signature=...",
"importData": {
"importId": "Import:abc123",
"entity": "Account",
"name": "Q1 Account Import",
"importStatus": "New"
}
}
Save the importId from the response — you will need it to check status and fetch errors.
Step 2: Upload the CSV File
Upload your CSV file to the pre-signed URL returned in Step 1 using a PUT request. The upload URL is valid for 1 hour — you do not need to construct the path yourself, just upload directly to the URL returned by the API.
curl -X PUT \
-H "Content-Type: text/csv" \
--data-binary @accounts.csv \
"https://s3.amazonaws.com/terros-imports/imports/Import:abc123/upload.csv?X-Amz-Signature=..."
Once the file is uploaded, processing begins automatically. The import transitions through these statuses:
| Status | Description |
|---|---|
New | Import created, waiting for file upload |
Uploaded | File received, queuing records |
Queued | Records enqueued for processing |
Processing | Records are being processed |
PostProcessing | Finalizing results |
Completed | Import finished successfully |
Failed | Import failed — check reason field for details |
Step 3: Poll for Status
Call Get Import to check the current status of your import:
curl -X POST "https://api.terros.com/import/get" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey $TERROS_API_KEY" \
-d '{ "importId": "Import:abc123" }'
Response:
{
"type": "success",
"log": {
"importId": "Import:abc123",
"entity": "Account",
"importStatus": "Completed",
"successes": 150,
"errors": 3,
"totalMessages": 153,
"completedAt": 1772665914046
}
}
Poll until importStatus is Completed or Failed. We recommend using exponential backoff (e.g. 5s, 10s, 20s, 40s) to avoid unnecessary requests for larger imports that take longer to process.
Fetching Errors
If the import has errors (errors > 0), call Get Import Errors to download the error details:
curl -X POST "https://api.terros.com/import/errors" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey $TERROS_API_KEY" \
-d '{ "importId": "Import:abc123" }'
Response:
{
"type": "success",
"records": [
{
"key": "imports/Import:abc123/errors/row-42.json",
"signedUrl": "https://s3.amazonaws.com/terros-imports/errors/row-42.json?X-Amz-Signature=..."
}
]
}
Each record contains a signedUrl — a temporary download link for the error file, valid for 12 hours. Download these files to see which rows failed and why.
Import Options
When initiating an import, you can pass these optional fields:
| Field | Type | Default | Applies To | Description |
|---|---|---|---|---|
entity | string | — | All | Required. The entity type to import |
name | string | — | All | A friendly name for the import |
disableGeocoding | boolean | false | Account, CalendarEvent, Contact, Recruit | Skip location resolution for addresses |
addMissingUsers | boolean | false | Account, Contact, Recruit, User | Automatically create users if they don't exist |
createCustomLocations | boolean | false | Account, CalendarEvent, Contact, Recruit | Create locations for new addresses |
notifyUsers | boolean | false | User | Send welcome emails to newly imported users |
workflowId | string | — | Account | Workflow to apply to imported records |
columnMapping | object | — | All | Maps CSV column names to the expected header names the parser should read them as |
Listing Imports
Call List Imports to see all imports for your company:
curl -X POST "https://api.terros.com/import/list" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey $TERROS_API_KEY" \
-d '{}'
Cleanup
After an import completes, you can call Cleanup Import to remove temporary data. Do not invoke cleanup while an import is still in progress — wait until the status reaches Completed or Failed.
curl -X POST "https://api.terros.com/import/cleanup" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey $TERROS_API_KEY" \
-d '{ "importId": "Import:abc123" }'