API conventions
Base URL, formats of IDs, timestamps and money, lists, and repeated requests.
Base URL and versions
https://api.deepscout.ai/v1The v1 in the path is the version of the API. The OpenAPI specification of the version is at /v1/openapi.json.
Requests and responses
- Send request bodies as JSON, with the header
Content-Type: application/json. - All responses are JSON, except file downloads.
- Field names are in
snake_case. Enum values are inUPPER_CASE, except the sign-inproviderof the account (googleorgithub).
Fields without a value
The API leaves out the fields that have no value. It does not send null. For example, a job without a settlement has no settlement field. In your code, read optional fields with a default:
percent = job.get("scrape_progress", {}).get("percent", 0)Fields with a default value, for example "sample": false, are always in the response.
IDs
All IDs are strings. Use them as opaque values: do not build them, and do not parse them.
| ID | Example |
|---|---|
project_id | proj_01k7c2r9v8e3s0b1x6m4q5n2tz |
customer_id | cust_01k7c2r9t2f8a5d3h7j9k1m6pw |
job_id | jobreq_01k7c3a4b5c6d7e8f9g0h1j2k3 |
key_id | key_01k7c4m2n3p4q5r6s7t8v9w0x1 |
website_id | example-shop.cz |
A website ID can contain a slash (/). You can put it in the path as it is.
Timestamps
Timestamps are strings in RFC 3339 format, in UTC, with milliseconds:
2026-10-13T09:00:00.000ZMoney
Amounts of money are decimal strings, not numbers, with the currency in a separate currency field. This keeps the exact value of each amount.
{ "currency": "EUR", "total": "12.88", "cap": "19.32" }Amounts have two decimal places. Convert the strings to a decimal type, not to a float:
from decimal import Decimal
cap = Decimal(job["estimate"]["cap"])Countries, currencies and languages
| Value | Format | Example |
|---|---|---|
| Country | Two-letter country code (ISO 3166-1 alpha-2). The API accepts any letter case and returns lower case. | cz |
| Currency | ISO 4217, in upper case. | CZK |
| Language | ISO 639-1. | cs |
Lists
- The job lists (setup, scraping, matching) show the newest jobs first.
limitsets the number of jobs, from 1 to 100. The default is 20. - The other lists return all items.
- Lists are JSON arrays, except the invoices and the usage, which have an
itemsfield, and the exports, which have anexportsfield.
Repeated requests
Some create requests are safe to send again:
| Request | When you send it again |
|---|---|
POST /jobs/setup | While a setup job for the same store, country and currency runs in the project, you get this job with 200 OK. After it ends, a new request creates a new job and uses another analysis. |
POST /jobs/scraping without urls | While the full scrape of the website is not finished, you get the same job with 200 OK. |
POST /contact-requests | For the same job, you get the first request with 200 OK. |
POST /jobs/scraping with urls | Each request creates a new job. |
POST /jobs/matching | The API answers 409 MATCHING_BUSY while the first matching is not finished. |
Approvals are also safe. A second approval of the same job answers 409 JOB_NOT_AWAITING_APPROVAL, and the API holds the credit only one time.
Long-running work
Jobs run in the background. The API has no webhooks yet. Read the job at an interval until it is in an end status. See Polling.