Create Feed Configuration
curl --request POST \
--url https://api.autosnap.com/v1/ims/feeds \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"dealership_id": "<string>",
"ftp_path": "<string>",
"file_name": "<string>",
"dealer_identifier": "<string>",
"staleness_threshold_hours": 48
}
'import requests
url = "https://api.autosnap.com/v1/ims/feeds"
payload = {
"api_key": "<string>",
"dealership_id": "<string>",
"ftp_path": "<string>",
"file_name": "<string>",
"dealer_identifier": "<string>",
"staleness_threshold_hours": 48
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
api_key: '<string>',
dealership_id: '<string>',
ftp_path: '<string>',
file_name: '<string>',
dealer_identifier: '<string>',
staleness_threshold_hours: 48
})
};
fetch('https://api.autosnap.com/v1/ims/feeds', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.autosnap.com/v1/ims/feeds",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'api_key' => '<string>',
'dealership_id' => '<string>',
'ftp_path' => '<string>',
'file_name' => '<string>',
'dealer_identifier' => '<string>',
'staleness_threshold_hours' => 48
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.autosnap.com/v1/ims/feeds"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.autosnap.com/v1/ims/feeds")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.autosnap.com/v1/ims/feeds")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Feed Management
Create Feed Configuration
Set up an IMS inventory feed configuration for a dealership.
POST
/
v1
/
ims
/
feeds
Create Feed Configuration
curl --request POST \
--url https://api.autosnap.com/v1/ims/feeds \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"dealership_id": "<string>",
"ftp_path": "<string>",
"file_name": "<string>",
"dealer_identifier": "<string>",
"staleness_threshold_hours": 48
}
'import requests
url = "https://api.autosnap.com/v1/ims/feeds"
payload = {
"api_key": "<string>",
"dealership_id": "<string>",
"ftp_path": "<string>",
"file_name": "<string>",
"dealer_identifier": "<string>",
"staleness_threshold_hours": 48
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
api_key: '<string>',
dealership_id: '<string>',
ftp_path: '<string>',
file_name: '<string>',
dealer_identifier: '<string>',
staleness_threshold_hours: 48
})
};
fetch('https://api.autosnap.com/v1/ims/feeds', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.autosnap.com/v1/ims/feeds",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'api_key' => '<string>',
'dealership_id' => '<string>',
'ftp_path' => '<string>',
'file_name' => '<string>',
'dealer_identifier' => '<string>',
'staleness_threshold_hours' => 48
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.autosnap.com/v1/ims/feeds"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.autosnap.com/v1/ims/feeds")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.autosnap.com/v1/ims/feeds")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key\": \"<string>\",\n \"dealership_id\": \"<string>\",\n \"ftp_path\": \"<string>\",\n \"file_name\": \"<string>\",\n \"dealer_identifier\": \"<string>\",\n \"staleness_threshold_hours\": 48\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}POST /v1/ims/feeds
AutoSnap-internal only. This endpoint is restricted to AutoSnap admin clients. Customers must email AutoSnap support to onboard a new IMS feed; non-admin API keys receive
403 ADMIN_REQUIRED.ims_vehicle table.
Before creating, the endpoint validates that:
- The SFTP directory exists and contains the specified file
- The file was modified within the last 48 hours (provider must be actively pushing)
- No existing feed config exists for this dealership + provider combination
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
api_key | string | Yes | — | Your API key |
dealership_id | string | Yes | — | Dealership public ID (e.g., dlr_8cfc0b00a98b) |
provider | string | Yes | — | IMS provider name. See supported providers below. |
ftp_path | string | Yes | — | Provider directory name on SFTP server (e.g., vauto, firstlook). This is the folder name under /import/ where the provider pushes files. |
file_name | string | Yes | — | Exact CSV filename to monitor (e.g., MP14015.csv). Must exist in the ftp_path directory. |
dealer_identifier | string | No | null | Dealer ID value within the CSV to filter rows. Required when multiple dealers share one CSV file (e.g., ProMax sends all dealers in one file). |
staleness_threshold_hours | integer | No | 48 | Hours without a file update before an ims.feed.stale webhook fires. |
Supported Providers
| Provider | Description | FTP Directory |
|---|---|---|
vauto | vAuto | vauto |
homenet | HomeNet | homenet |
vincue | VinCue | vincue |
promax | ProMax | promax |
maxdigital | MaxDigital / Firstlook | firstlook |
inventoryplus | InventoryPlus | inventoryplus |
dealercenter | DealerCenter | dealercenter |
idms | IDMS | idms |
ansira | Ansira | ansira |
The
provider field determines which field mapping is used to parse the CSV. The ftp_path field determines which directory on the SFTP server to look in. These may differ — for example, MaxDigital uses provider: "maxdigital" but ftp_path: "firstlook".Example
curl -X POST "https://api.autosnap.com/v1/ims/feeds" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"dealership_id": "dlr_8cfc0b00a98b",
"provider": "vauto",
"ftp_path": "vauto",
"file_name": "MP14015.csv",
"staleness_threshold_hours": 48
}'
Multi-dealer file example (ProMax)
When a provider sends all dealers in a single CSV, usedealer_identifier to filter:
curl -X POST "https://api.autosnap.com/v1/ims/feeds" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"dealership_id": "dlr_abc123",
"provider": "promax",
"ftp_path": "promax",
"file_name": "Preownedplus.csv",
"dealer_identifier": "9553"
}'
Response
{
"id": "ims_config_b9648b954a07",
"status": "created"
}
The first import will not occur until the provider pushes a file. Creating a feed config tells AutoSnap where to look — but if the provider hasn’t sent the file yet, there is nothing to import. The 60-second polling means that once the file arrives, it will be picked up within a minute.To know when the first import completes, subscribe to the
ims.import.complete webhook event before creating the feed config. This webhook fires as soon as the file is successfully parsed and all vehicles are imported. You can then call GET /v1/ims/vehicles to retrieve the inventory.If the file is already present on SFTP when you create the config (verified by the 48-hour freshness check), the first import will typically complete within 60 seconds.Errors
| Status | Detail | Cause |
|---|---|---|
400 | No CSV files found in /import/{ftp_path}/ | The SFTP directory doesn’t exist or is empty |
400 | File '{file_name}' not found... | The specified file doesn’t exist. Response includes a list of available files. |
400 | File '{file_name}' is N days old... | The file hasn’t been updated in over 48 hours. The provider isn’t actively pushing. |
400 | Invalid provider | Provider name not in the supported list |
403 | Not authorized for this dealership | Your API key doesn’t have access to this dealership |
404 | Dealership not found | Invalid or unknown dealership_id |
409 | Feed config already exists... | A feed for this dealership + provider already exists |
502 | SFTP connection failed | Could not connect to the SFTP server to validate the feed path and file |
Body
application/json
Public ID (e.g. dlr_xxx) or internal ID
Available options:
vauto, homenet, vincue, promax, maxdigital, inventoryplus, dealercenter, idms, ansira Provider directory name on SFTP (e.g. vauto, firstlook)
Exact CSV filename on SFTP (e.g. MP14015.csv)
Dealer ID within the CSV for multi-dealer files
Response
Feed created