Overview
| Field | Value |
|---|---|
| Base URL | https://rennsic.com/api/ |
| Auth | Bearer token |
| Rate limits | 120/min, 30/min on VIN lookups |
| Credit cost | 1 / new VIN |
| Plans with API access | Pro, Dealer |
| OpenAPI schema | /api/schema/ |
Every route reads and writes the same registry the console uses: one credit pool, one search history, no separate API dataset. A VIN already paid for re-runs free and refreshes the plan's retention window; a structurally impossible VIN is rejected with a 400 before any credit is spent.
Authentication
Exchange credentials for a token, then send it as
Authorization: Bearer <key> on
every request after. A signed-in account finds and regenerates its
token on
your account page, once signed in.
POST /api/auth-token/
Content-Type: application/json
{"username": "[email protected]", "password": "********"}
{"token": "9558b6e17dfa4c2e8f0b1a3d7c6e5f4a2b1c0d9e"}
error field replaces it otherwise.
Accounts with IP whitelist entries accept requests only from those addresses, token or not; manage them under Manage IP restrictions on your account page.
Connect AI agents
Claude, Cursor, and other MCP clients run the same lookups: connectors sign in with your account, developer tools send the API token. Same credits, same history, same rate limits as the REST API.
What a connected agent gets back and the workflows it fits into are on the Agents page.
https://rennsic.com/api/mcp/
Streamable HTTP, stateless
- Settings → Connectors → Add custom connector
-
Paste
https://rennsic.com/api/mcp/ - Connect, sign in to Rennsic, approve
No token or client ID: the connector registers itself and lookups run against your signed-in account. ChatGPT developer-mode connectors take the same URL.
claude mcp add --transport http rennsic \
https://rennsic.com/api/mcp/ \
--header "Authorization: Bearer <your-token>"
# ~/.cursor/mcp.json
{
"mcpServers": {
"rennsic": {
"url": "https://rennsic.com/api/mcp/",
"headers": {
"Authorization": "Bearer <your-token>"
}
}
}
}
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: mcp-client-2025-11-20" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Check VIN 1HGBH41JXMN109186 for rental history."}
],
"mcp_servers": [{
"type": "url",
"url": "https://rennsic.com/api/mcp/",
"name": "rennsic",
"authorization_token": "<your-token>"
}],
"tools": [{"type": "mcp_toolset", "mcp_server_name": "rennsic"}]
}'
Agent skill, from rennsic/rennsic-skill
/plugin marketplace add rennsic/rennsic-skill
/plugin install rennsic-vin-history@rennsic
| Tool | Cost | Purpose |
|---|---|---|
| vin_lookup | 1 credit, new VIN | Rental history for one VIN; a paid VIN re-runs free |
| search_history | Free | Past lookups on the account, 25 per page |
| credit_usage | Free | Credit balance and request counts |
| request_report | Free | Generate the PDF report for a VIN already paid for |
| Prompt | Argument | Purpose |
|---|---|---|
| check_vin | vin | One lookup; the argument autocompletes from VINs the account has paid for |
| account_status | none | Balance and recent lookups, from the two free tools |
Endpoints
Seven routes: two for authentication, three for a VIN and its report, and two that read the account's history and balance. All but the first require the bearer token above.
| Method | Path | Cost | |
|---|---|---|---|
| POST | /api/auth-token/ | Unauthenticated | Exchange credentials for a token |
| GET | /api/auth-token/verify/ | Free | Validate a token, return account identity |
| GET | /api/vin/{vin}/ | 1 credit, new VIN | Look up a VIN's commercial rental history |
| POST | /api/vin/{vin}/report/ | Free | Generate the PDF report for a VIN already looked up |
| GET | /api/vin/{vin}/report/download/ | Free | Download that PDF once it is ready |
| GET | /api/history/ | Free | Paginated history of past lookups |
| GET | /api/credit-usage/ | Free | Credit balance and request counts |
/api/auth-token/
Exchange a username and password for a bearer token.
| Field | In | Notes |
|---|---|---|
| username | body | Account username or email |
| password | body | Account password |
Returns: 200, 400, 403, 429.
/api/auth-token/verify/
Validate the current token and return the account it belongs to.
{"valid": true, "username": "you", "email": "[email protected]"}
Returns: 200, 401, 403, 429.
/api/vin/{vin}/
Look up one VIN's (9-17 characters) commercial rental history in the indexed peer-to-peer rental listing database; a malformed VIN is rejected with 400 before any credit is spent.
{
"found": true,
"cached": false,
"vin": "WP0AB2A97ES121028",
"record_url": "https://rennsic.com/vehicles/WP0AB2A97ES121028/",
"report": {"status": "none", "download_url": null},
"summary": {
"total_trips": 145,
"listing_count": 1,
"rental_history_count": 1,
"identity": {"year": 2014, "make": "Porsche", "model": "911", "trim": "S (2WD), 4S (4WD)"},
"usage_stats": {"overall_percentile": 94, "make_percentile": 90, "model_percentile": 88}
},
"listings": [
{
"trips_on_record": 145,
"current": {"tripCount": 145, "location": {"display": "Miami, FL"}},
"history": []
}
],
"review_risk": {
"pending": false,
"progress": null,
"scoring_version": "v4+agg1rt",
"issue_count": 2,
"evidence_comments": 3,
"total_comments": 61,
"newest_comment_date": "2025-11-04",
"coverage_note": "2 findings across 61 reviews, most recent 2025-11-04",
"flags": ["modified"],
"flag_labels": ["Modified / non-stock"],
"findings": [
{"category": "mechanical", "category_label": "Mechanical", "severity": "moderate", "trip_impact": "partial", "excerpt": "check engine light came on halfway through the trip", "comment_date": "2025-11-04", "rank": 1}
]
}
}
Returns: 200, 400, 402, 403, 429.
Field notes
| Field | Meaning |
|---|---|
| found | True on a match; false is a complete, paid answer, not an error. |
| cached | True when this account already paid for the VIN; no credit spent. |
| record_url | The account's record page; 404s once retention on the VIN lapses. |
| identity | Decoded year, make, model, trim; top-level on a miss, nested in summary on a hit. |
| summary | Trip totals and percentiles; present only when found is true. |
| listings | One entry per owner rental history, with trip count and current listing. |
| report | PDF status; download_url is a one-hour signed link once ready. |
| model_percentile | Rank within make and model; null when that cohort is too small to rank fairly. |
| review_risk | Null when no review data is indexed, never that the car is clean. |
| issue_count | Distinct issues renters reported, the headline; coverage_note gives the evidence behind it, flag_labels the disclosures, findings the quotes. There is no 0-100 rating. |
| pending / progress | True while classifying, which the first paid lookup of a VIN starts; progress reports work done, never a time estimate. |
/api/vin/{vin}/report/
Start generating the branded PDF report for a VIN (path parameter) this account has already looked up; free, since the entitlement was bought with the lookup. A report asked for while the VIN's reviews are still being classified waits briefly for that analysis, and one that printed without it is re-rendered in place when the analysis lands, so the same download gains the review section without a second request.
{"status": "pending", "download_url": null}
Returns: 200, 202, 400, 404, 429.
/api/vin/{vin}/report/download/
Download the PDF for a VIN with a ready report on this account, using the bearer token or a signed-in browser session; this is the account's stable, never-expiring address for the file, unlike the one-hour signed download_url returned elsewhere.
curl -OJ "https://rennsic.com/api/vin/WP0AB2A97ES121028/report/download/" \
-H "Authorization: Bearer <your-token>"
Returns: 200, 404, 429 (200 is application/pdf).
/api/history/
Every lookup this account has made, most recent first, from either the console or the API.
| Parameter | In | Default | Notes |
|---|---|---|---|
| page | query | 1 | Page number |
| page_size | query | 25 | Results per page, capped at 100 |
{
"count": 142,
"next": "https://rennsic.com/api/history/?page=2",
"previous": null,
"results": [
{
"vin": "WP0AB2A97ES121028",
"success": true,
"cached": false,
"credits_deducted": true,
"searched_at": "2026-08-30T14:02:11Z"
}
]
}
Returns: 200, 429.
/api/credit-usage/
The current credit balance, plus API request counts for this month and all time.
{"credits_remaining": 42, "requests_this_month": 18, "requests_total": 233}
Returns: 200, 429.
Errors and limits
Every error is a JSON body with an error
field carrying a plain-language message; the status code says which
case it is.
| Status | Meaning |
|---|---|
| 400 | Malformed VIN. Rejected before any credit is spent. |
| 401 | Missing or invalid bearer token. |
| 402 | Credit balance is spent. Buy more credits or wait for the plan's renewal. |
| 403 | No active plan, no API-access plan, or an IP outside the account's whitelist. |
| 404 | No report for this VIN on this account, or it aged out of the retention window. |
| 410 | A signed report download link aged out past its one hour. |
| 429 | Rate limit reached. See the throttle rates below. |
| Scope | Rate | Applies to |
|---|---|---|
| user | 120/min | Every authenticated request, the account-wide ceiling |
| vin_lookup | 30/min | GET /api/vin/{vin}/, on top of the user rate |
| auth_token | 10/min | POST /api/auth-token/, by IP address |
| anon | 20/min | Unauthenticated requests, by IP address |
Retry-After.