Renta Docs

Error Handling

How to handle API errors, status codes, and validation failures in the Renta API.

All Renta API errors return a consistent JSON structure with an HTTP status code, error type, and human-readable message.

Error Response Format

{
  "error": {
    "type": "validation_error",
    "message": "Invalid input",
    "errors": [
      {
        "field": "pickup_date",
        "message": "Required"
      },
      {
        "field": "return_date",
        "message": "Must be after pickup_date"
      }
    ]
  }
}

HTTP Status Codes

StatusTypeDescription
400validation_errorInvalid request parameters
401authentication_errorInvalid or missing API key
402payment_failedPayment processing failed (Stripe error)
403authorization_errorInsufficient API key scope
404not_foundResource doesn't exist
409conflictResource conflict (e.g., double booking, active bookings on delete)
422validation_errorSemantic validation failure
429rate_limit_exceededToo many requests
500internal_errorServer error (auto-retried by SDK)

Handling Errors with the SDK

The SDK throws typed exceptions for every error:

import {
  Renta,
  RentaError,
  RentaAuthError,
  RentaNotFoundError,
  RentaValidationError,
  RentaConflictError,
  RentaRateLimitError,
  RentaInternalError,
} from '@renta/sdk';

const renta = new Renta({ apiKey: process.env.RENTA_API_KEY! });

try {
  await renta.bookings.create({
    customer_id: 'cust_abc',
    pickup_date: '2026-07-01T09:00:00Z',
    return_date: '2026-07-03T17:00:00Z',
    line_items: [{ fleet_item_id: 'fi_nonexistent' }],
  });
} catch (err) {
  if (err instanceof RentaValidationError) {
    // Field-level validation errors
    console.log('Validation errors:');
    for (const fieldErr of err.errors) {
      console.log(`  ${fieldErr.field}: ${fieldErr.message}`);
    }
  } else if (err instanceof RentaNotFoundError) {
    console.log(`Resource not found: ${err.message}`);
    console.log(`Request ID: ${err.requestId}`);
  } else if (err instanceof RentaConflictError) {
    console.log(`Conflict: ${err.message}`);
  } else if (err instanceof RentaRateLimitError) {
    console.log(`Rate limited. Retry after ${err.retryAfter}s`);
  } else if (err instanceof RentaAuthError) {
    console.log('Check your API key');
  } else if (err instanceof RentaInternalError) {
    console.log('Server error — will auto-retry');
  }
}

Error Class Reference

Error ClassHTTP StatusWhen
RentaAuthError401, 403Invalid or insufficient API key
RentaNotFoundError404Resource doesn't exist
RentaValidationError400, 422Invalid input (includes errors array with field-level details)
RentaConflictError409Resource conflict (e.g., double booking)
RentaRateLimitError429Too many requests (has retryAfter property)
RentaInternalError500+Server error (auto-retried by default)

All error classes extend RentaError, which has:

interface RentaError {
  message: string;    // Human-readable error message
  type: string;       // Error type identifier
  status: number;     // HTTP status code
  requestId?: string; // Unique request ID for support
}

Automatic Retries

The SDK automatically retries on:

  • 429 (Rate Limited) — respects Retry-After header, exponential backoff
  • 5xx (Server Errors) — exponential backoff with jitter, capped at 30s

Default: 3 retries. Disable with:

const renta = new Renta({
  apiKey: process.env.RENTA_API_KEY!,
  maxRetries: 0, // disable retries
});

Request IDs

Every API response includes a unique x-request-id header. Include this when contacting support:

try {
  await renta.bookings.get('bk_nonexistent');
} catch (err) {
  if (err instanceof RentaError) {
    console.log(`Request ID: ${err.requestId}`);
    // → "req_abc123def456"
  }
}

Always log request IDs in production. They help Renta support trace specific requests across our infrastructure.