apiauto-space 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apiauto_space-0.1.0/.gitignore +25 -0
- apiauto_space-0.1.0/CHANGELOG.md +26 -0
- apiauto_space-0.1.0/LICENSE +21 -0
- apiauto_space-0.1.0/PKG-INFO +378 -0
- apiauto_space-0.1.0/README.md +347 -0
- apiauto_space-0.1.0/examples/async_search.py +34 -0
- apiauto_space-0.1.0/examples/search.py +54 -0
- apiauto_space-0.1.0/examples/sync_changes.py +62 -0
- apiauto_space-0.1.0/pyproject.toml +86 -0
- apiauto_space-0.1.0/src/apiauto/__init__.py +79 -0
- apiauto_space-0.1.0/src/apiauto/_async_client.py +247 -0
- apiauto_space-0.1.0/src/apiauto/_base.py +301 -0
- apiauto_space-0.1.0/src/apiauto/_client.py +246 -0
- apiauto_space-0.1.0/src/apiauto/_version.py +1 -0
- apiauto_space-0.1.0/src/apiauto/errors.py +91 -0
- apiauto_space-0.1.0/src/apiauto/py.typed +0 -0
- apiauto_space-0.1.0/src/apiauto/types.py +218 -0
- apiauto_space-0.1.0/tests/conftest.py +79 -0
- apiauto_space-0.1.0/tests/test_async_client.py +151 -0
- apiauto_space-0.1.0/tests/test_client.py +405 -0
- apiauto_space-0.1.0/tests/test_live.py +80 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# Environments
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
.env
|
|
12
|
+
.env.*
|
|
13
|
+
|
|
14
|
+
# Tools
|
|
15
|
+
.pytest_cache/
|
|
16
|
+
.mypy_cache/
|
|
17
|
+
.ruff_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
htmlcov/
|
|
20
|
+
|
|
21
|
+
# Editors and OS
|
|
22
|
+
.idea/
|
|
23
|
+
.vscode/
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.0] — 2026-10-27
|
|
8
|
+
|
|
9
|
+
First release.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `Client` and `AsyncClient` for the apiauto.space API: Encar (Korea), Che168 (China),
|
|
14
|
+
Copart and IAAI (USA).
|
|
15
|
+
- Catalog search with typed filters: `cars()`, `iter_cars()` with `max_items`, `car()`.
|
|
16
|
+
- Change feed: `changes()` and `iter_changes()`; `since` takes a `datetime` or an ISO 8601 string.
|
|
17
|
+
- References and usage: `brands()`, `models()`, `dictionaries()`, `markets()`, `usage()`.
|
|
18
|
+
- Live US search: `us_live()`.
|
|
19
|
+
- Exceptions per API error (`BadRequestError`, `AuthenticationError`, `QuotaExceededError`,
|
|
20
|
+
`PermissionDeniedError`, `NotFoundError`, `RateLimitError`, `ServerError`,
|
|
21
|
+
`ServiceUnavailableError`, `APIConnectionError`).
|
|
22
|
+
- Retries on 429 and 503 after `Retry-After`, and on 5xx and network errors with backoff.
|
|
23
|
+
- Quota and rate-limit headers in `client.last_response`.
|
|
24
|
+
- `TypedDict` types for every response and `py.typed`.
|
|
25
|
+
|
|
26
|
+
[0.1.0]: https://github.com/apiauto-space/apiauto-python/releases/tag/v0.1.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 apiauto.space
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: apiauto-space
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the apiauto.space used-car API: Encar (Korea), Che168 (China), Copart and IAAI (USA) listings in one JSON format
|
|
5
|
+
Project-URL: Homepage, https://apiauto.space/en/
|
|
6
|
+
Project-URL: Documentation, https://apiauto.space/en/docs/
|
|
7
|
+
Project-URL: Repository, https://github.com/apiauto-space/apiauto-python
|
|
8
|
+
Project-URL: Issues, https://github.com/apiauto-space/apiauto-python/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/apiauto-space/apiauto-python/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Get a demo key, https://t.me/apiautospace_bot?start=demo
|
|
11
|
+
Author: apiauto.space
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: api client,car auction,car listings,che168,che168 api,chinese cars,copart,copart api,encar,encar api,iaai,korean cars,used cars,vehicle data
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Requires-Dist: httpx<1,>=0.27
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# apiauto — Python client for the Encar, Che168, Copart and IAAI API
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/apiauto-space/)
|
|
35
|
+
[](https://pypi.org/project/apiauto-space/)
|
|
36
|
+
[](https://github.com/apiauto-space/apiauto-python/blob/main/LICENSE)
|
|
37
|
+
|
|
38
|
+
`apiauto` is a typed Python client for the [apiauto.space](https://apiauto.space/en/) REST API: used-car
|
|
39
|
+
listings from **Encar** (South Korea), **Che168** (China) and the **Copart** and **IAAI** auctions (USA) in
|
|
40
|
+
one JSON record format, without writing a scraper. Search the catalogs by make, model, year, price and
|
|
41
|
+
mileage, page through whole markets, follow a feed of new cars, sold cars and price changes, and read
|
|
42
|
+
quota headers — from sync or async code. It is an unofficial client: the project is not affiliated with
|
|
43
|
+
Encar, Che168/Autohome, Copart or IAAI; the data comes through the apiauto.space API.
|
|
44
|
+
|
|
45
|
+
- Sync `Client` and `AsyncClient` on top of [httpx](https://www.python-httpx.org/), the only dependency
|
|
46
|
+
- Iterators that follow the cursor for you, with `max_items` that never over-spends the quota
|
|
47
|
+
- Automatic retries on 429 and 503 (honouring `Retry-After`) and on 5xx and network errors
|
|
48
|
+
- One exception class per API error: `QuotaExceededError`, `RateLimitError`, `NotFoundError` ...
|
|
49
|
+
- `TypedDict` types for every response, `py.typed`, checked with `mypy --strict`
|
|
50
|
+
- Python 3.10+
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install apiauto-space
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The distribution is called `apiauto-space` on PyPI; the module you import is `apiauto`.
|
|
59
|
+
|
|
60
|
+
## Get a key
|
|
61
|
+
|
|
62
|
+
Open the Telegram bot [@apiautospace_bot](https://t.me/apiautospace_bot?start=demo) and take a free demo
|
|
63
|
+
key: one day, 100 data requests, up to 20 cars per request, all three markets. Paid plans are on the
|
|
64
|
+
[pricing page](https://apiauto.space/en/#pricing).
|
|
65
|
+
|
|
66
|
+
Save the key in the `APIAUTO_KEY` environment variable — the client reads it from there:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
export APIAUTO_KEY="your-key"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Keep the key on your server. The API does not accept browser requests (CORS is off), and a key in page
|
|
73
|
+
code is visible to every visitor.
|
|
74
|
+
|
|
75
|
+
## Quick start
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import apiauto
|
|
79
|
+
|
|
80
|
+
client = apiauto.Client() # reads APIAUTO_KEY
|
|
81
|
+
|
|
82
|
+
page = client.cars("kr", brand="Kia", model="Sorento", year_min=2021, limit=20)
|
|
83
|
+
for car in page["items"]:
|
|
84
|
+
print(car["id"], car["title"], car["price"]["amount"], car["price"]["currency"])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Markets are `kr` (Encar, Korea), `cn` (Che168, China) and `us` (Copart and IAAI, USA). Every record has
|
|
88
|
+
the same keys in every market; a value the source does not provide is `None`.
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
### Search Encar by make, model, year and price
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
page = client.cars(
|
|
96
|
+
"kr",
|
|
97
|
+
brand="Hyundai",
|
|
98
|
+
model="Grandeur",
|
|
99
|
+
year_min=2020,
|
|
100
|
+
year_max=2023,
|
|
101
|
+
price_min=10_000_000, # in the market's currency: KRW for Korea; skips monthly lease payments
|
|
102
|
+
price_max=30_000_000,
|
|
103
|
+
mileage_max=80_000, # km
|
|
104
|
+
sort="-first_seen", # newest listings first (the default)
|
|
105
|
+
limit=20,
|
|
106
|
+
)
|
|
107
|
+
print(page["count"], "cars match") # None when more than 10,000 match
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Prices in dollars at the ECB rate work in every market: `price_usd_min=15000, price_usd_max=25000`.
|
|
111
|
+
The full list of filters: `brand`, `model`, `generation` (Korea), `trim`, `year_min`, `year_max`,
|
|
112
|
+
`price_min`, `price_max`, `price_usd_min`, `price_usd_max`, `mileage_max`, `fuel`, `transmission`,
|
|
113
|
+
`body_type`, `has_photos`, `is_active`, `q` (words of the title), `sort`, `limit`, `cursor`.
|
|
114
|
+
|
|
115
|
+
### Search Che168 (China)
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
for car in client.cars("cn", brand="BYD", fuel="electric", has_photos=True, limit=10)["items"]:
|
|
119
|
+
print(car["title"], car["price"]["amount"], "CNY", car["location"]["city"])
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### US auction lots: Copart and IAAI
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
for lot in client.cars("us", brand="Toyota", model="Camry", year_min=2020, limit=10)["items"]:
|
|
126
|
+
raw = lot["raw"] # auction-only fields as the source sends them
|
|
127
|
+
print(lot["id"], lot["vin"], lot["mileage_km"], raw.get("damage_main"), raw.get("sale_date"))
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Cars that are not in the copy yet can be searched live at the auction data provider (Pro and Max plans,
|
|
131
|
+
a separate monthly counter): `client.us_live(make="Toyota", model="Camry", year_min=2020)`.
|
|
132
|
+
|
|
133
|
+
### Iterate over all pages
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
for car in client.iter_cars("kr", brand="Genesis", limit=100, max_items=1000):
|
|
137
|
+
save(car)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`iter_cars` follows `next_cursor` until the last page. With `max_items` the last request asks only for
|
|
141
|
+
the cars still needed, so the quota is not spent on records that would be thrown away. The demo allows
|
|
142
|
+
`limit` up to 20; paid plans up to 100.
|
|
143
|
+
|
|
144
|
+
### Get a car by id
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
car = client.car("encar:43020893")
|
|
148
|
+
print(car["is_active"], car["listing_url"])
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Ids look like `encar:…`, `che168:…`, `copart:…` and `iaai:…` and never change. A sold or removed car
|
|
152
|
+
stays available for 14 days with `is_active=False`.
|
|
153
|
+
|
|
154
|
+
### Keep a catalog in sync with the change feed
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
import time
|
|
158
|
+
from datetime import datetime, timezone
|
|
159
|
+
|
|
160
|
+
since = datetime.now(timezone.utc)
|
|
161
|
+
while True:
|
|
162
|
+
time.sleep(3600) # the market copy is refreshed hourly
|
|
163
|
+
polled_at = datetime.now(timezone.utc)
|
|
164
|
+
for event in client.iter_changes("kr", since, limit=100):
|
|
165
|
+
if event["type"] == "added":
|
|
166
|
+
save(client.car(event["car_id"]))
|
|
167
|
+
elif event["type"] == "disappeared":
|
|
168
|
+
mark_sold(event["car_id"])
|
|
169
|
+
else: # price_drop or price_up
|
|
170
|
+
update_price(event["car_id"], event["new_price"])
|
|
171
|
+
since = polled_at
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`since` takes a `datetime` (a naive one is treated as UTC) or an ISO 8601 string. Filter by
|
|
175
|
+
`type="price_drop"` (or a list of types) and `min_pct=5`. The feed comes with the Pro, Max and demo
|
|
176
|
+
plans; each event counts as one record. A complete script is in
|
|
177
|
+
[examples/sync_changes.py](https://github.com/apiauto-space/apiauto-python/blob/main/examples/sync_changes.py).
|
|
178
|
+
|
|
179
|
+
### References: makes, models, canonical values, freshness
|
|
180
|
+
|
|
181
|
+
These calls are free.
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
client.brands("cn") # [{"name": "Mercedes-Benz", "count": 20185}, ...]
|
|
185
|
+
client.models("kr", "Hyundai") # the make's models with car counts
|
|
186
|
+
client.dictionaries()["fuel"] # {"gasoline": ["gasoline", "petrol", ...], "diesel": [...], ...}
|
|
187
|
+
for market in client.markets():
|
|
188
|
+
print(market["market"], market["active_cars"], market["data_age_seconds"], market["stale"])
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Usage and quota headers
|
|
192
|
+
|
|
193
|
+
The quota counts returned cars (records), not requests; the demo counts data requests.
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
usage = client.usage() # free
|
|
197
|
+
print(usage["plan"], usage["quota_used"], "/", usage["quota_limit"], usage["quota_unit"])
|
|
198
|
+
|
|
199
|
+
client.cars("us", limit=5)
|
|
200
|
+
info = client.last_response
|
|
201
|
+
print(info.quota_remaining, info.quota_reset, info.rate_remaining, info.data_age_seconds)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`client.last_response` is a frozen `ResponseInfo` read from the `X-Quota-*`, `X-RateLimit-*` and
|
|
205
|
+
`X-Data-Age-Seconds` headers of the last response; a header that was not sent is `None`.
|
|
206
|
+
|
|
207
|
+
### Async
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
import asyncio
|
|
211
|
+
import apiauto
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
async def main() -> None:
|
|
215
|
+
async with apiauto.AsyncClient() as client:
|
|
216
|
+
page = await client.cars("cn", brand="Toyota", limit=10)
|
|
217
|
+
async for car in client.iter_cars("kr", brand="Kia", max_items=50):
|
|
218
|
+
print(car["title"])
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
asyncio.run(main())
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`AsyncClient` has the same methods as `Client`; `iter_cars` and `iter_changes` return async iterators.
|
|
225
|
+
|
|
226
|
+
### Errors and retries
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
try:
|
|
230
|
+
car = client.car("encar:1")
|
|
231
|
+
except apiauto.NotFoundError:
|
|
232
|
+
car = None
|
|
233
|
+
except apiauto.QuotaExceededError as error:
|
|
234
|
+
print("quota renews at", error.reset_at)
|
|
235
|
+
except apiauto.ApiautoError as error:
|
|
236
|
+
print(error.status_code, error.code, error.detail)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
| HTTP | Exception | Retried |
|
|
240
|
+
| --- | --- | --- |
|
|
241
|
+
| 400 | `BadRequestError` | no |
|
|
242
|
+
| 401 | `AuthenticationError` | no |
|
|
243
|
+
| 402 | `QuotaExceededError` | no |
|
|
244
|
+
| 403 | `PermissionDeniedError` | no |
|
|
245
|
+
| 404 | `NotFoundError` | no |
|
|
246
|
+
| 429 | `RateLimitError` | yes, after `Retry-After` |
|
|
247
|
+
| 500, 502 | `ServerError` | yes, exponential backoff |
|
|
248
|
+
| 503 | `ServiceUnavailableError` | yes, after `Retry-After` |
|
|
249
|
+
| — | `APIConnectionError` (network, timeout) | yes, exponential backoff |
|
|
250
|
+
|
|
251
|
+
All of them derive from `ApiautoError`. Retries follow the
|
|
252
|
+
[API's error guide](https://apiauto.space/en/docs/errors/): `max_retries=2` by default, a wait of at most
|
|
253
|
+
60 seconds; `Client(max_retries=0)` turns them off. Other options: `Client(api_key=..., base_url=...,
|
|
254
|
+
timeout=30.0, http_client=httpx.Client(...))`.
|
|
255
|
+
|
|
256
|
+
### Photos
|
|
257
|
+
|
|
258
|
+
`car["photos"]` are signed links that work for about a day. Store the car's `id`, not the links, and
|
|
259
|
+
fetch a fresh record with `client.car(id)` when you need the photos again. Photo requests are free and
|
|
260
|
+
may redirect to the original host, so follow redirects when downloading them.
|
|
261
|
+
|
|
262
|
+
### Prices are decimal strings
|
|
263
|
+
|
|
264
|
+
Prices, dollar prices and percentages come as strings such as `"23900000.00"` so no precision is lost.
|
|
265
|
+
Convert them with `Decimal`:
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
from decimal import Decimal
|
|
269
|
+
|
|
270
|
+
total = sum(Decimal(car["price_usd"]) for car in page["items"] if car["price_usd"])
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## A record
|
|
274
|
+
|
|
275
|
+
A real Encar car from the [documentation](https://apiauto.space/en/docs/record/), shortened: two photo
|
|
276
|
+
links and a few `raw` fields.
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"id": "encar:43020893",
|
|
281
|
+
"market": "kr",
|
|
282
|
+
"source": "encar",
|
|
283
|
+
"source_id": "43020893",
|
|
284
|
+
"title": "2020 Kia Mohave The Master 3.0 4WD 7-seater Masters",
|
|
285
|
+
"brand": "Kia",
|
|
286
|
+
"model": "Mohave",
|
|
287
|
+
"generation": "Mohave The Master",
|
|
288
|
+
"trim": "3.0 4WD 7-seater Masters",
|
|
289
|
+
"year": 2020,
|
|
290
|
+
"mileage_km": 93724,
|
|
291
|
+
"fuel": "diesel",
|
|
292
|
+
"transmission": null,
|
|
293
|
+
"engine_cc": null,
|
|
294
|
+
"body_type": null,
|
|
295
|
+
"color": null,
|
|
296
|
+
"vin": null,
|
|
297
|
+
"price": {"amount": "23900000.00", "currency": "KRW"},
|
|
298
|
+
"price_usd": "18033.96",
|
|
299
|
+
"location": {"country": "KR", "region": "Gyeonggi", "city": null},
|
|
300
|
+
"photos": [
|
|
301
|
+
"https://api.apiauto.space/img/encar:43020893/1.jpg?exp=…&sig=…",
|
|
302
|
+
"https://api.apiauto.space/img/encar:43020893/2.jpg?exp=…&sig=…"
|
|
303
|
+
],
|
|
304
|
+
"photo_count": 4,
|
|
305
|
+
"listing_url": "https://fem.encar.com/cars/detail/43020893",
|
|
306
|
+
"is_active": true,
|
|
307
|
+
"first_seen_at": "2026-10-26T04:37:32.553458Z",
|
|
308
|
+
"last_seen_at": "2026-10-26T04:37:32.553458Z",
|
|
309
|
+
"disappeared_at": null,
|
|
310
|
+
"updated_at": "2026-10-26T04:37:32.553458Z",
|
|
311
|
+
"source_mode": "replica",
|
|
312
|
+
"raw": {"badge": "디젤 3.0 4WD 7인승", "form_year": "202004", "sell_type": "normal", "has_accident": false}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
The fields each source adds are described on the [Encar API](https://apiauto.space/en/encar-api/),
|
|
317
|
+
[Che168 API](https://apiauto.space/en/che168-api/), [Copart API](https://apiauto.space/en/copart-api/) and
|
|
318
|
+
[IAAI API](https://apiauto.space/en/iaai-api/) pages.
|
|
319
|
+
|
|
320
|
+
## Methods
|
|
321
|
+
|
|
322
|
+
| Method | Endpoint | Returns | Quota |
|
|
323
|
+
| --- | --- | --- | --- |
|
|
324
|
+
| `cars(market, **filters)` | `GET /v1/cars` | `CarsPage`: `items`, `next_cursor`, `count` | per car |
|
|
325
|
+
| `iter_cars(market, *, max_items=None, **filters)` | `GET /v1/cars` | iterator of `Car` | per car |
|
|
326
|
+
| `car(car_id)` | `GET /v1/cars/{id}` | `Car` | 1 |
|
|
327
|
+
| `changes(market, since, *, type, min_pct, limit, cursor)` | `GET /v1/changes` | `ChangesPage` | per event |
|
|
328
|
+
| `iter_changes(market, since, *, type, min_pct, limit, max_items)` | `GET /v1/changes` | iterator of `Change` | per event |
|
|
329
|
+
| `brands(market)` | `GET /v1/references/brands` | list of `{name, count}` | free |
|
|
330
|
+
| `models(market, brand)` | `GET /v1/references/models` | list of `{name, count}` | free |
|
|
331
|
+
| `dictionaries()` | `GET /v1/references/dictionaries` | field → canonical value → synonyms | free |
|
|
332
|
+
| `markets()` | `GET /v1/references/markets` | list of `Market` | free |
|
|
333
|
+
| `usage()` | `GET /v1/usage` | `Usage` | free |
|
|
334
|
+
| `us_live(*, make, model, year_min, year_max, price_max, page)` | `GET /v1/us/live` | list of `Car` | own counter |
|
|
335
|
+
|
|
336
|
+
The API reference: [apiauto.space/en/docs](https://apiauto.space/en/docs/) and the
|
|
337
|
+
[OpenAPI schema](https://api.apiauto.space/openapi.json).
|
|
338
|
+
|
|
339
|
+
## Other languages
|
|
340
|
+
|
|
341
|
+
| Language | Package | Repository |
|
|
342
|
+
| --- | --- | --- |
|
|
343
|
+
| Python | `pip install apiauto-space` | [apiauto-space/apiauto-python](https://github.com/apiauto-space/apiauto-python) |
|
|
344
|
+
| JavaScript, TypeScript | `npm install apiauto` | [apiauto-space/apiauto-js](https://github.com/apiauto-space/apiauto-js) |
|
|
345
|
+
| curl, PHP and more | — | [apiauto-space/encar-api-examples](https://github.com/apiauto-space/encar-api-examples) |
|
|
346
|
+
|
|
347
|
+
## По-русски
|
|
348
|
+
|
|
349
|
+
`apiauto` — Python-клиент для API Encar, Che168, Copart и IAAI, без парсинга: объявления о подержанных
|
|
350
|
+
автомобилях из Южной Кореи, Китая и с аукционов США приходят в одном формате JSON через
|
|
351
|
+
[apiauto.space](https://apiauto.space/). Клиент умеет искать по марке, модели, году, цене и пробегу,
|
|
352
|
+
сам проходит по страницам курсором, повторяет запрос при 429 и 503 и работает в синхронном и асинхронном
|
|
353
|
+
коде. Бесплатный демо-ключ на сутки выдаёт Telegram-бот
|
|
354
|
+
[@apiautospace_bot](https://t.me/apiautospace_bot?start=demo); сохраните его в переменной `APIAUTO_KEY`
|
|
355
|
+
и держите на сервере, не в браузере. Документация на русском: [apiauto.space/docs](https://apiauto.space/docs/).
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
pip install apiauto-space
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
import apiauto
|
|
363
|
+
|
|
364
|
+
client = apiauto.Client() # ключ из APIAUTO_KEY
|
|
365
|
+
for car in client.cars("kr", brand="Kia", year_min=2021, limit=20)["items"]:
|
|
366
|
+
print(car["title"], car["price"]["amount"], car["price"]["currency"])
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## License
|
|
370
|
+
|
|
371
|
+
[MIT](https://github.com/apiauto-space/apiauto-python/blob/main/LICENSE) © 2026 apiauto.space
|
|
372
|
+
|
|
373
|
+
## Disclaimer
|
|
374
|
+
|
|
375
|
+
This is an unofficial client of the apiauto.space API. It is not affiliated with, endorsed by or
|
|
376
|
+
sponsored by Encar, Che168, Autohome, Copart or IAAI; their names are used only to describe where the
|
|
377
|
+
listings come from, and all trademarks belong to their owners. Use of the data is subject to the
|
|
378
|
+
[apiauto.space terms](https://apiauto.space/en/offer/).
|