Overview
Everything you need to integrate with the Stile HTTP API from any language.
The Stile API is a standard REST API. Any language that can make HTTP requests can integrate — no SDK required.
Widget handles the client side
Most integrations only need the widget (<stile-button>) for the frontend and a webhook handler on the backend. You may never need to call the API directly.
Base URL
https://api.stile.dev/v1/Authentication
Pass your secret key as a Bearer token in the Authorization header:
curl https://api.stile.dev/v1/verification_sessions \
-H "Authorization: Bearer vk_test_YOUR_SECRET_KEY" \
-H "Content-Type: application/json"See Authentication for key types (publishable vs secret) and rate limits.
Making a request
Here's the same API call — creating a verification session — in every supported language:
curl -X POST https://api.stile.dev/v1/verification_sessions \
-H "Authorization: Bearer vk_test_..." \
-H "Content-Type: application/json" \
-d '{"type": "age", "use_case": "alcohol_delivery"}'import requests
res = requests.post(
"https://api.stile.dev/v1/verification_sessions",
headers={"Authorization": "Bearer vk_test_..."},
json={"type": "age", "use_case": "alcohol_delivery"},
)
session = res.json()body := strings.NewReader(`{"type":"age","use_case":"alcohol_delivery"}`)
req, _ := http.NewRequest("POST", "https://api.stile.dev/v1/verification_sessions", body)
req.Header.Set("Authorization", "Bearer vk_test_...")
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)import Stile from "@stile/node";
const stile = new Stile("vk_test_...");
const session = await stile.verificationSessions.create({
type: "age",
use_case: "alcohol_delivery",
});Request format
- Content-Type:
application/jsonfor all POST requests - Query parameters: for GET requests and filtering
# POST — JSON body
curl -X POST https://api.stile.dev/v1/verification_sessions \
-H "Authorization: Bearer vk_test_..." \
-H "Content-Type: application/json" \
-d '{"type": "age", "use_case": "alcohol_delivery"}'
# GET — query parameters
curl "https://api.stile.dev/v1/verification_sessions?limit=10&status=verified" \
-H "Authorization: Bearer vk_test_..."Response format
Every resource includes an object field identifying its type:
{
"id": "vks_abc123",
"object": "verification_session",
"status": "verified",
"type": "age",
"created": 1741564800
}Pagination
List endpoints use cursor-based pagination:
| Parameter | Description |
|---|---|
limit | Number of results (1-100, default 10) |
starting_after | Cursor: return results after this ID |
ending_before | Cursor: return results before this ID |
The response includes has_more to indicate whether more results exist:
{
"object": "list",
"url": "/v1/verification_sessions",
"has_more": true,
"data": [...]
}To paginate forward, pass the last item's id as starting_after:
curl "https://api.stile.dev/v1/verification_sessions?limit=10&starting_after=vks_abc123" \
-H "Authorization: Bearer vk_test_..."Expanding responses
Some endpoints support the expand[] parameter to include related objects inline:
# Include verification results in the session response
curl "https://api.stile.dev/v1/verification_sessions/vks_abc123?expand[]=results" \
-H "Authorization: Bearer vk_test_..."Errors
All errors return a JSON body with this structure:
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "No such verification_session: 'vks_unknown'",
"param": "id",
"request_id": "req_abc123"
}
}Include the request_id when contacting support. See Error Handling for all status codes and error types.
Idempotency
POST requests accept an Idempotency-Key header to prevent duplicates:
curl -X POST https://api.stile.dev/v1/verification_sessions \
-H "Authorization: Bearer vk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_12345" \
-d '{"type": "age", "use_case": "alcohol_delivery"}'If a request with the same key was already processed, the original response is returned without creating a duplicate.
Rate limiting
Requests are rate-limited per API key:
| Key type | Limit |
|---|---|
Test keys (vk_test_) | 100 req / min |
Live keys (vk_live_) | 1,000 req / min |
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1741564920When exceeded, the API returns 429 with a Retry-After header. Wait the specified seconds before retrying.
Node.js SDK
If you prefer a typed client for Node.js / TypeScript, the @stile/node package wraps every endpoint documented here. Every SDK method maps 1:1 to an HTTP call — choose whichever you prefer.