Coming Soon

Need to push / pull data that isn't listed yet? No problem! Contact our support team & we'll jump right on it.

Importing Data

The /import endpoint allows you to update, create, and delete data using a JSON format.

NOTE: This endpoint requires your API Token to have write permissions enabled.

REQUEST

In the control panel, Data Imports stop after validation so you can preview the changes and manually run (or not run) the import. The API is different.

When you import data with the API, the changes will be automatically applied (assuming there are no validation errors). You can use the dryRun option if you wish to only validate the changes.

Like the rest of the API, you'll make a POST request with JSON listing the changes to be made along with some options such as failure notifications, etc.

POST /import
Host: https://api.firm.app
Content-Type: application/json

{
  "apiKey": "YOUR_API_KEY_GOES_HERE",
  "apiSecret": "YOUR_API_SECRET_GOES_HERE",
  "apiVersion": "1",
  "endpointId": "import",
  "dryRun": false,
  "failureNotificationEmails": [
    "[email protected]"
  ],
  "successNotificationEmails": [],
  "filename": "owners-20241220.json",
  "recordSets": [
    {
      "schema": "client",
      "lookup": "email",
      "records": [
        {
          "name": "John Doe",
          "email": "[email protected]"
        },
        {
          "name": "Jane Doe",
          "email": "[email protected]"
        }
      ]
    }
  ]
}

If you wish to use SFTP instead of the API, please contact our support team and we'll get you set up. Likewise, if you prefer a CSV format for the API then we can also help get that set up.

REQUEST OPTIONS

These options go in the root request object as demonstrated above.

Field Type Description Required
dryRun boolean Defaults to false. Set to true to skip the "save" step. All other actions will be performed (such as notifications). false
wait boolean Defaults to false. Allows you to receive the result of the import in this API call instead of using the /importStatus endpoint. Learn More false
successNotificationEmails string[] An array of email addresses which will be sent an alert if the import is successful. false
failureNotificationEmails string[] An array of email addresses which will be sent an alert if the import fails for any reason. false
filename string The name of this import. Optional. Shown in the control panel as though it were the filename. It is helpful to include info on what is being loaded and date information. Extension is optional and meaningless. false
recordSets IRecordSet[] Each record set is a json object containing options and records. See more below.

RECORD SETS

A data import can load multiple types of records at the same time - for example, clients and list items can both be loaded in the same update. Each of these types should be in their own recordSet json object.

Field Type Description Required
schema string Schema tells the system what type of data you're working on. This field is not case or whitespace sensitive. See all the available schemas within your control panel. Some schemas are available to all organization such as client, professional, list, etc. true
lookup string
Like the spreadsheet version of data imports, the system will "lookup" each record using the field you provide. This lookup is neither case nor whitespace sensitive. If that record is not found, then a record will be created.
The id field is a common option. That means the system will lookup the user by it's database id, then update the other fields accordingly. However (1) you probably don't know the database id and (2) this makes it impossible to create new records.
So you might use email as the lookup field. The system will search for someone with the given email address and update their other fields. If the user is not found, a profile would then be created. Learn More
true
records Record[] Each record is a JSON object that includes your lookup field along with any other fields you're wanting to change. Look at the schema docs to see exactly what fields are available for the schema you choose. See the example below. true

This example does two things. First, it finds the person via their email "[email protected]" and updates his Cell Phone number. Second, it finds the State titled "Texas" and updates the code to "TEX".

{
  "apiKey": "...",
  "recordSets": [
    {
      "schema": "Client",
      "lookup": "email",
      "records": [
        {
          "email": "[email protected]",
          "cellPhone": "555 555-1234"
        }
      ]
    },
    {
      "schema": "ListItem.States",
      "lookup": "title",
      "records": [
        {
          "title": "Texas",
          "code": "TEX"
        }
      ]
    }
  ]
}

RESPONSE

This endpoint does not wait for the import to complete as it may take several minutes. Instead, this endpoint returns an importId which you may use with the /importStatus endpoint to check the status and results.

The response will be a JSON object which has the same format as other API endpoints. This means it will always include the fields ok (boolean), meta (object), and an optional error object. If the endpoint was able to at least create a data import validation record then a importId will also be included.

Field Type Description Required
ok boolean true means the update was successful. false means it failed for any reason.
error object An error object including a message, code, and status (HTTP status code).
For example: {"message":"Validation failed","code":"invalid_request","status":400}
importId string The unique id of the data import which can be viewed in the control panel or queried via API. If the import fails early enough in the process, it is possible that this value is null and an error will be returned.

SAMPLE RESPONSE

{
  "ok": false,
  "importId": "dltn8flp0qtjkmuhghnod",
  "error": {
    "code": "bad_request",
    "message": "The data import was valid. Record #2 contained the error...",
    "status": 400
  },
  "meta": {
    "requestId": "v9uumk6y1j2l4tn8flp0qtjkmuhghnod",
    "duration": 25,
    "rateLimitRemaining": 97,
    "rateLimitLimit": 100
  }
}

NOTE You may use the wait option to force this request to wait for the import to complete. Not recommended. If you use this option, the API may self-redirect several times and the end response will be the same as the /importStatus endpoint.