stile
Guides

Error Handling

stile uses conventional HTTP status codes and structured error objects. The Node.js SDK surfaces these as typed error classes.

Error response format

All API errors return a JSON body in this shape:

{
  "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 — it lets us trace the exact request in our logs.

HTTP status codes

CodeMeaning
200OK — request succeeded.
201Created — resource was created successfully.
400Bad Request — missing or invalid parameters.
401Unauthorized — invalid, missing, or revoked API key.
404Not Found — the requested resource doesn't exist.
409Conflict — idempotency key collision or state conflict.
422Unprocessable Entity — the request is valid but can't be fulfilled.
429Too Many Requests — rate limit exceeded. Retry after the Retry-After header value.
500Internal Server Error — something went wrong on our end. Retry with exponential backoff.

Error types

TypeWhen it occurs
invalid_request_errorA parameter is missing, invalid, or the operation isn't allowed in the current state.
authentication_errorThe API key is missing, malformed, revoked, or expired.
rate_limit_errorToo many requests were sent in the current window.
api_errorAn unexpected server error occurred. Safe to retry.

SDK error classes

The Node.js SDK provides typed error classes so you can handle different failures precisely:

import {
  StileError,
  StileAuthenticationError,
  StileRateLimitError,
} from "@stile/node";

async function createSession() {
  try {
    return await stile.verificationSessions.create({ type: "identity" });
  } catch (err) {
    if (err instanceof StileAuthenticationError) {
      // 401 — your key is invalid, revoked, or missing
      console.error("Check your STILE_API_KEY environment variable");
      throw err;
    }

    if (err instanceof StileRateLimitError) {
      // 429 — back off and retry
      const retryAfter = err.retryAfter ?? 60;
      console.warn(`Rate limited. Retry in ${retryAfter}s`);
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      return createSession();
    }

    if (err instanceof StileError) {
      console.error({
        type: err.type,
        code: err.code,
        message: err.message,
        statusCode: err.statusCode,
        requestId: err.requestId,
      });
      throw err;
    }

    throw err;
  }
}

Retrying requests

The Node.js SDK automatically retries network errors and 5xx responses with exponential backoff (up to maxRetries times, default: 2). You can increase this for resilient background jobs:

const stile = new Stile(process.env.STILE_API_KEY!, {
  maxRetries: 5, // retry up to 5 times for transient errors
});

Don't retry 4xx errors automatically

Client errors (400, 401, 404, 429) indicate a problem with the request itself. Retrying them immediately won't help — fix the underlying issue first. The SDK only auto-retries network failures and 5xx responses.

Idempotency

Use the idempotency_key field when creating sessions to prevent duplicates if your request is retried after a network timeout:

const session = await stile.verificationSessions.create({
  type: "identity",
  client_reference_id: userId,
  idempotency_key: `verify-${userId}-${Date.now()}`,
});

On this page