Conventions
The same rules apply to every endpoint.
Basics
- Base URL
https://api.stilo.io/v1. HTTPS and JSON only. - Ids are opaque strings with a type prefix:
prd_product,var_variant,ret_retailer,lnk_link. Brands use their slug (nars). - Money is
{"amount": "15990.00", "currency": "CLP"}: a decimal string plus its ISO 4217 currency. Never assume a currency, and never add amounts in different currencies. - Commission rates are decimal strings from 0 to 1 (
"0.12"= 12%), a fraction of the sale without VAT. Rates are current, not guaranteed: each sale is decided when it happens. - Timestamps are ISO 8601 in UTC.
- You see brands and products of your market (the country of your stilo account).
Pagination
Lists return data and next_cursor. Pass next_cursor back as cursor until it is null. limit goes from 1 to 100 (default 50).
GET /v1/products?brand=nars&limit=100
GET /v1/products?brand=nars&limit=100&cursor=WyIyMDI2LTEw...Errors
Every error has the same shape. Branch on type, which is stable; message is for humans.
{
"error": {
"type": "not_commissionable",
"message": "This store is not in the stilo network.",
"param": "url",
"request_id": "req_a8e9c161ff2a89b85743a8be"
}
}| Status | When |
|---|---|
| 400 | The request is malformed (invalid_request). |
| 401 / 403 | Authentication or permission problems. See Authentication. |
| 404 | The thing does not exist or is not visible to you (not_found). |
| 409 | Idempotency-Key reused with a different request (idempotency_conflict). |
| 422 | Valid request refused by a business rule, e.g. not_commissionable, product_not_found. |
| 429 | Rate limited (rate_limited). Wait Retry-After seconds. |
| 5xx | Our side. Safe to retry with backoff. |
Every response carries a Stilo-Request-Id header. Include it when you write to us.
Rate limits
| Limit | Default |
|---|---|
| Requests | 600 per minute, all your keys together |
| New links | 20,000 per day (UTC). Existing links are always returned. |
| Batch size | 100 items per POST /v1/links/batch |
Responses carry RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds). A 429 includes Retry-After. Need more? Write to contacto@stilo.io.
Idempotency
Link creation is already idempotent: one link per product and store. For retries of batch calls, send an Idempotency-Key header (any unique string). The same key and body within 24 hours returns the first response with Idempotent-Replayed: true.
Versioning
The version is in the path (/v1). Within v1 we only add things: new endpoints, new fields, new error types. Write clients that ignore fields they don't know. A breaking change ships as /v2 with at least 90 days' notice, announced in the changelog.