Setup Dealer
curl --request POST \
--url https://api.autosnap.com/v1/dealers/setup \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"dealership_url": "<string>",
"dealer_name": "<string>",
"city": "<string>",
"state": "<string>",
"street_address": "<string>",
"phone_number": "<string>",
"async_mode": false
}
'import requests
url = "https://api.autosnap.com/v1/dealers/setup"
payload = {
"api_key": "<string>",
"dealership_url": "<string>",
"dealer_name": "<string>",
"city": "<string>",
"state": "<string>",
"street_address": "<string>",
"phone_number": "<string>",
"async_mode": False
}
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_url: '<string>',
dealer_name: '<string>',
city: '<string>',
state: '<string>',
street_address: '<string>',
phone_number: '<string>',
async_mode: false
})
};
fetch('https://api.autosnap.com/v1/dealers/setup', 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/dealers/setup",
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_url' => '<string>',
'dealer_name' => '<string>',
'city' => '<string>',
'state' => '<string>',
'street_address' => '<string>',
'phone_number' => '<string>',
'async_mode' => false
]),
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/dealers/setup"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"dealership_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\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/dealers/setup")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"dealership_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.autosnap.com/v1/dealers/setup")
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_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Dealers
Setup Dealership
Onboard a new dealership for inventory data collection.
POST
/
v1
/
dealers
/
setup
Setup Dealer
curl --request POST \
--url https://api.autosnap.com/v1/dealers/setup \
--header 'Content-Type: application/json' \
--data '
{
"api_key": "<string>",
"dealership_url": "<string>",
"dealer_name": "<string>",
"city": "<string>",
"state": "<string>",
"street_address": "<string>",
"phone_number": "<string>",
"async_mode": false
}
'import requests
url = "https://api.autosnap.com/v1/dealers/setup"
payload = {
"api_key": "<string>",
"dealership_url": "<string>",
"dealer_name": "<string>",
"city": "<string>",
"state": "<string>",
"street_address": "<string>",
"phone_number": "<string>",
"async_mode": False
}
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_url: '<string>',
dealer_name: '<string>',
city: '<string>',
state: '<string>',
street_address: '<string>',
phone_number: '<string>',
async_mode: false
})
};
fetch('https://api.autosnap.com/v1/dealers/setup', 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/dealers/setup",
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_url' => '<string>',
'dealer_name' => '<string>',
'city' => '<string>',
'state' => '<string>',
'street_address' => '<string>',
'phone_number' => '<string>',
'async_mode' => false
]),
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/dealers/setup"
payload := strings.NewReader("{\n \"api_key\": \"<string>\",\n \"dealership_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\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/dealers/setup")
.header("Content-Type", "application/json")
.body("{\n \"api_key\": \"<string>\",\n \"dealership_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.autosnap.com/v1/dealers/setup")
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_url\": \"<string>\",\n \"dealer_name\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"street_address\": \"<string>\",\n \"phone_number\": \"<string>\",\n \"async_mode\": false\n}"
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}POST /v1/dealers/setup
v1.0 schema lock. The response shape on this page is the locked v1.0 contract. We will never remove a documented field, never rename a field, and never change a field’s type without bumping to v2 (see Versioning). New fields may be added additively; your client must tolerate unknown keys. This endpoint has two distinct success-response variants: async job creation (HTTP 202 — the standard flow) and reactivation (HTTP 200 — when an inactive subscription exists for the URL).
How It Works
- POST this endpoint. You get back HTTP 202 with a
setup_idin well under a second. - The setup job (provider detection, AI config validation, subscription creation) runs in the background — typically 60 seconds, up to ~10 minutes for heavily bot-protected sites.
- Poll
GET /v1/dealers/setup/{setup_id}untilstatusis"completed"or"failed". Recommended polling interval: 5 seconds. - Or skip polling: subscribe to the
setup.completewebhook before calling setup.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
api_key | string | Yes | — | Your API key. Accepted in body (canonical) or ?api_key=… query string. |
dealership_url | string | Yes | — | The dealership’s website URL (e.g. https://www.baydodge.net). Any form is accepted — with or without the scheme, www, or a trailing slash. Responses return the dealership’s canonical host (baydodge.net); the exact string you sent is echoed back as requested_url on the status endpoint and on the setup.complete / setup.failed webhooks. |
dealer_name | string | No | — | Override the detected dealer name |
city | string | No | — | Dealer city (used if auto-detection can’t determine location) |
state | string | No | — | Dealer state |
street_address | string | No | — | Dealer street address |
phone_number | string | No | — | Dealer phone number |
condition_filter | string | No | null | Filter inventory by condition. Values: "new", "used", or null (all conditions). When set, only vehicles matching this condition are included in imports for this subscription. |
async_mode | boolean | No | — | Deprecated, ignored. Setup is always asynchronous. The field is tolerated for backward compatibility. |
Example
curl -X POST "https://api.autosnap.com/v1/dealers/setup" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"dealership_url": "https://www.baydodge.net"
}'
Response — HTTP 202 Accepted
{
"success": true,
"setup_id": "setup_6420ad759b71",
"status": "pending",
"message": "Setup job created. Poll GET /v1/dealers/setup/{setup_id} for status, or wait for the setup.complete webhook.",
"poll_url": "/v1/dealers/setup/setup_6420ad759b71"
}
curl "https://api.autosnap.com/v1/dealers/setup/setup_6420ad759b71?api_key=YOUR_API_KEY"
pending, running, completed, failed). When status is "completed", the poll response carries the detected provider, provider_confidence, config, vehicle_counts, and the new dealership_id / configuration_id / subscription_id.
setup_status on the completed poll response is "active" when detection and validation both pass. If detection succeeds but the test scrape has issues (e.g. missing critical fields), the status is "needs_manual_review" — imports are still created but may need attention, and the poll response includes a human-readable requires_review_reason.
status: "completed" means detection and configuration are done — NOT that inventory is available. Poll until inventory_status: "available", or subscribe to the import.complete webhook. See Get Setup Status for details.Inventory is automatically refreshed every 12 hours. This is the default schedule for all new dealerships and is not configurable via the API.
URL format in responses. Every dealership is keyed on its canonical host, so
https://www.baydodge.net is stored and returned as baydodge.net in dealership_url / website_url everywhere in the API. To map a response or webhook back to your own request, use setup_id (returned with the 202) or dealership_id (returned when setup completes and carried on every webhook), or read requested_url — the URL exactly as you submitted it.Re-adding a dealership you deleted
Calling setup again for a dealership you previously deleted works like any setup: it returns HTTP 202 with asetup_id, and you receive setup.complete (or setup.failed) when it finishes.
- If you deleted it within the last 7 days and its inventory was still importing successfully, we reuse its previous configuration once a quick test scrape confirms it still works. This finishes faster than a new setup.
- Otherwise, or if that test fails (for example because the dealer changed website providers), we detect the website again from scratch.
{
"success": true,
"reactivated": true,
"subscription_id": 221,
"configuration_id": 9,
"website_url": "baydodge.net",
"message": "Dealership subscription reactivated"
}
Errors
| Status | Description |
|---|---|
| 409 | Dealership is already actively subscribed under your account |
| 422 | Request body failed validation (e.g. missing dealership_url) |
| 422 | code: INVALID_URL: dealership_url is not a valid website address (for example, an invalid domain ending such as .com123456). Returned immediately; no setup is created. |
| 503 | Setup queue unavailable — the job could not be enqueued. Safe to retry. |
Detection failures (e.g. the website provider could not be identified) no longer surface as POST errors — the POST succeeds with 202, and the failure is reported on the poll response as
status: "failed" with an error message and, when available, a failure_mode classification.