AutoUncle Data Services is in beta. The API, MCP tools and agent skill may change often, including breaking changes, until version 1.0. Read the changelog before you upgrade an integration.
Retrieve, replay & reconcile
Valuations are synchronous and there are no webhooks: the answer comes back in the response. This guide covers what to do when you did not get that response, how to read a recorded result again, and how to reconcile your records with ours.
Three tools
| Tool | Use it when | Costs |
|---|---|---|
Replay: resend the same body with the same Idempotency-Key |
You do not know whether a request completed | Free. Never charges twice. |
Read back: GET /v1/valuations/{request_id} |
You have the request_id and want the recorded result again |
Free. Counts towards the per-minute rate limit. |
| Console logs and usage CSV | You want to audit or reconcile many requests | Free |
Replay an unknown outcome
A timeout, a dropped connection or a crashed worker leaves you not knowing whether the valuation was recorded (and charged). Resend exactly the same body with the same key:
- If the first request finished, you get its recorded outcome back, valued, refused or failed, with
usage.idempotent_replay: trueandusage.credits_used: 0.usage.original_credits_usedshows whether the original was charged. - If it never arrived, the valuation runs now, once.
- If it is still running, you get
409request_in_progress. Wait briefly and replay again with the same key.
The body comparison ignores the order of JSON keys, but every value must be identical. A different body with the same key returns 409 idempotency_conflict. Keys are scoped to your workspace and to test or live mode. Idempotency has the full rules.
{
"usage": {
"billable": false,
"credits_used": 0,
"original_credits_used": 0,
"credits_remaining": 0,
"cache_hit": false,
"idempotent_replay": true,
"mode": "test"
}
}
Note: A replay returns the recorded outcome, including a recorded failure. To make a fresh attempt after a confirmed
failedorrefusedresult, use a new key. See errors & retries.
Read a result back
Store the request_id (val_…) from the response body; the X-Valuation-Id response header carries the same value. The X-Request-Id header is the HTTP request ID, which is a different value. To read the result later:
curl https://data-services.autouncle.com/v1/valuations/val_0123456789abcdef0123456789abcdef \
-H "Authorization: Bearer $AUTOUNCLE_API_KEY"
require "json"
require "net/http"
uri = URI("https://data-services.autouncle.com/v1/valuations/val_0123456789abcdef0123456789abcdef")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("AUTOUNCLE_API_KEY")}"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts JSON.pretty_generate(JSON.parse(response.body))
import json
import os
import requests
response = requests.get(
"https://data-services.autouncle.com/v1/valuations/val_0123456789abcdef0123456789abcdef",
headers={
"Authorization": f"Bearer {os.environ['AUTOUNCLE_API_KEY']}",
},
timeout=30,
)
print(json.dumps(response.json(), indent=2))
const response = await fetch("https://data-services.autouncle.com/v1/valuations/val_0123456789abcdef0123456789abcdef", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.AUTOUNCLE_API_KEY}`,
},
});
console.log(JSON.stringify(await response.json(), null, 2));
The read-back:
- returns the result as it was recorded, including the
notesandattributionsthat applied at the time, even if a source's notice has changed since; - does not include the
usageblock; - needs the
valuations:readscope, and a key of the same mode: a test key cannot read a live result and vice versa; - is private to your workspace. Another workspace's ID returns
404not_found, as does an unknown ID.
Over MCP, the get_valuation tool returns the same result. See the tool reference.
Why there is no polling loop
You never need to poll for completion: POST /v1/valuations returns the final outcome within its processing budget (about eight seconds; see how valuations work). The only "in progress" state you can observe is request_in_progress, when you replay a key whose first request has not finished. Wait a second or two and replay.
Reconcile with your records
To make sure every vehicle you meant to value has an outcome:
- Before sending, persist the idempotency key you will use with your own row, in state
pending. - After a response, store
request_id,statusand the result, and mark the row done. - On restart, replay every row still
pendingwith its stored key and body. Recorded rows come back for free; the rest are valued now. - Periodically, compare against the console:
- Request logs lists recent requests with their status and request ID, and can be filtered by status (
valued,refused,failed,pending) or by a specific request ID. - Usage shows requests and credits by day, week or month, and exports up to 10,000 rows as CSV with
request_id,date,mode,source,status,credits,duration_msandcountry.
- Request logs lists recent requests with their status and request ID, and can be filtered by status (
source in the CSV tells you where a request came from: the REST API, MCP or the console playground.
Re-valuing over time
A recorded valuation is a snapshot for its valuation_date. To value the same car again later (for example monthly for a fleet), send a new request with a new key that includes the date or period, such as fleet-AB12345-2026-11. Reusing last month's key would only replay last month's result.
Pitfalls
- Generating the key after the request. If the key only exists in memory when the process dies, you cannot replay. Store it first.
- Using the wrong header.
GET /v1/valuations/{id}needs theval_…ID from the body or theX-Valuation-Idheader, not theX-Request-Idheader. - Expecting usage on read-back. Use the POST response, or the console, for billing details.