Pricing Endpoints

Reference for Sails pricing APIs, including price prediction and appraisal workflows with request and response examples.

POST

/api/v1/predict-price

10 credits

Predict Price

Analyze a publicly accessible image URL and return visually similar product listings with price data. The response always includes an error object (empty on success), a results array, and a normalized price range (price_lower/price_upper).

Request Body

image_urlstringREQUIRED

Publicly accessible image URL to analyze. JPG, PNG, and WebP formats are supported.

descriptionstringOPTIONAL

Optional text description of the item to improve matching.

countrystringOPTIONAL

ISO 3166-1 alpha-2 country code used for localization and currency normalization. Defaults to au.

limitintegerOPTIONAL

Maximum number of product results to return (capped at 60). Omit to return all available matches.

Response Example

{
  "price_lower": 120.0,
  "price_upper": 180.0,
  "price_currency": "AUD",
  "results": [
    {
      "title": "Nike Air Max 90",
      "price": "120.00",
      "url": "https://www.nike.com/...",
      "image": "https://img.example.com/...",
      "vendor": "Nike"
    },
    {
      "title": "Air Max 90 - White/Black",
      "price": "",
      "url": "https://www.example-retailer.com/...",
      "image": "",
      "vendor": "Example Retailer"
    }
  ],
  "error": {}
}

Response Fields

price_lowernumber

Lower bound of the price range in the currency implied by the request country (default au -> AUD). Null when no prices can be normalized.

price_uppernumber

Upper bound of the price range in the currency implied by the request country (default au -> AUD). Null when no prices can be normalized.

price_currencystring

ISO 4217 currency code derived from the request country (default au -> AUD).

resultsarray<object>

List of product matches. Empty when no matches or on error.

results[].titlestring

Product title from the listing; may include variant details.

results[].pricestring

Normalized price string in the request currency. Empty string when unavailable.

results[].urlstring

Listing URL for the product; may include tracking parameters.

results[].imagestring

Image URL for the listing. Empty string when unavailable.

results[].vendorstring

Retailer name; empty string when unavailable.

errorobject

Empty object on success. On error, contains code/message and optional url/httpStatus.

error.codestring

Stable error identifier (e.g. BAD_REQUEST, RATE_LIMIT). Present only on error.

error.messagestring

Human-readable error details. Present only on error.

error.urlstring

URL that failed during navigation, when available.

error.httpStatusinteger

Upstream HTTP status encountered (e.g. 429). Optional.

error.image_upload_errorsarray<object>

Non-fatal image normalization failures for results[].image. Empty or omitted when none occur.

error.image_upload_errors[].indexinteger

Index of the result item whose image failed to normalize.

error.image_upload_errors[].product_urlstring

Listing URL associated with the failed image.

error.image_upload_errors[].imagestring

Original image payload that failed to parse.

error.image_upload_errors[].reasonstring

Reason the image failed to parse or upload.

Errors

UNAUTHORIZEDHTTP 401

Missing or invalid Authorization header or API key.

OUT_OF_CREDITSHTTP 402

Out of credits.

BAD_REQUESTHTTP 400

Missing image_url or invalid limit.

NAVIGATION_ERRORHTTP 502

Upstream navigation failed while fetching results.

RATE_LIMITHTTP 429

Upstream rate limit encountered.

SERVER_ERRORHTTP 500

Server misconfiguration or missing required credentials.

UNKNOWNHTTP 500

Unexpected error.

Example Error Response

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Missing image_url."
  },
  "results": []
}
curl -X POST https://sails.live/api/v1/predict-price \
-H "Authorization: Bearer sails_sk_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/sneakers.jpg",
"description": "Black Nike Air Max 90 on a white background",
"country": "au",
"limit": 10
}'
Customise Example
POST

/api/v1/appraise-product

10 credits

Appraise Product

Appraise an item from a public image URL and return an authoritative price range, best match (if any), defect hints, and enriched comparable listings.

Request Body

image_urlstringREQUIRED

Publicly accessible image URL to appraise. JPG, PNG, and WebP formats are supported.

descriptionstringOPTIONAL

Optional text description of the item to guide appraisal.

countrystringOPTIONAL

ISO 3166-1 alpha-2 country code used for localization and currency normalization. Defaults to au.

limitintegerOPTIONAL

Maximum number of similar items to enrich and return (1-10, default 10).

Response Example

{
  "similar_items": [
    {
      "title": "Polaroid SX-70",
      "price": 265.0,
      "currency": "GBP",
      "url": "https://example.com/listing",
      "image": "https://img.example.com/...",
      "vendor": "Example Retailer"
    }
  ],
  "appraisal": {
    "price_lower": 240.0,
    "price_upper": 300.0,
    "price_currency": "GBP",
    "best_match": {
      "title": "Polaroid SX-70",
      "price": 265.0,
      "currency": "GBP",
      "url": "https://example.com/listing",
      "image": "https://img.example.com/...",
      "vendor": "Example Retailer"
    },
    "reasoning": [
      "Recent UK listings for similar SX-70 models cluster between 240-300 GBP.",
      "Light cosmetic wear supports a mid-range appraisal."
    ],
    "defects": [
      "Minor scuffing visible on leather panel."
    ]
  },
  "error": {
    "discovery_error": null,
    "image_upload_errors": [],
    "price_enrichment_errors": [],
    "appraisal_error": null,
    "defect_error": null
  }
}

Response Fields

similar_itemsarray<object>

Comparable listings enriched with numeric prices in the target currency.

similar_items[].titlestring

Title of the comparable listing.

similar_items[].pricenumber

Normalized numeric price in the target currency (null if unavailable).

similar_items[].currencystring

ISO 4217 currency code for the normalized price.

similar_items[].urlstring

Listing URL.

similar_items[].imagestring

Image URL for the listing (empty string when unavailable).

similar_items[].vendorstring

Retailer or marketplace name.

appraisalobject

Appraisal output including authoritative range, best match, and reasoning.

appraisal.price_lowernumber

Lower bound of the appraisal range.

appraisal.price_uppernumber

Upper bound of the appraisal range.

appraisal.price_currencystring

ISO 4217 currency code for the appraisal.

appraisal.best_matchobject

Best comparable listing when an exact match is found, otherwise null.

appraisal.reasoningarray<string>

Bullet reasoning for the appraisal range.

appraisal.defectsarray<string>

Defect hints derived from the image.

errorobject

Non-fatal warnings and pipeline errors (empty fields on success).

error.discovery_errorobject

Discovery failure with code/message when no similar items can be found.

error.image_upload_errorsarray<object>

Image normalization failures (empty when none occur).

error.price_enrichment_errorsarray<object>

Per-item enrichment errors with index/url/message.

error.appraisal_errorobject

Appraisal stage errors; fallback appraisal is returned when set.

error.defect_errorobject

Defect stage errors; defects array will be empty when set.

Errors

UNAUTHORIZEDHTTP 401

Missing or invalid Authorization header or API key.

OUT_OF_CREDITSHTTP 402

Out of credits.

BAD_REQUESTHTTP 400

Missing image_url or invalid request fields.

NAVIGATION_ERRORHTTP 502

Upstream navigation failed while fetching results.

RATE_LIMITHTTP 429

Upstream rate limit encountered.

SERVER_ERRORHTTP 500

Server misconfiguration or missing required credentials.

UNKNOWNHTTP 500

Unexpected error.

Example Error Response

{
  "similar_items": [],
  "appraisal": {
    "price_lower": null,
    "price_upper": null,
    "price_currency": null,
    "best_match": null,
    "reasoning": [],
    "defects": []
  },
  "error": {
    "discovery_error": {
      "code": "BAD_REQUEST",
      "message": "Missing image_url."
    },
    "image_upload_errors": [],
    "price_enrichment_errors": [],
    "appraisal_error": null,
    "defect_error": null
  }
}
curl -X POST https://sails.live/api/v1/appraise-product \
-H "Authorization: Bearer sails_sk_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/vintage-camera.jpg",
"description": "Vintage Polaroid SX-70, light wear on leather body",
"country": "au",
"limit": 10
}'
Customise Example