stile
HTTP API

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/json for 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:

ParameterDescription
limitNumber of results (1-100, default 10)
starting_afterCursor: return results after this ID
ending_beforeCursor: 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 typeLimit
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: 1741564920

When 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.

On this page