Fleet API
Manage rental inventory — categories and items with pricing, availability, and deposit configuration.
The Fleet API manages your rental inventory. Fleet is organized into categories (e.g., "E-Bikes", "Kayaks") and items (individual rentable units).
Categories
List Categories
GET /v1/fleet/categoriesReturns all fleet categories for your tenant.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
cursor | string | Pagination cursor |
limit | integer | Results per page (1–100, default 20) |
const categories = await renta.fleet.categories.list();
console.log(categories.data);curl https://api.getrenta.io/v1/fleet/categories \
-H "Authorization: Bearer renta_sk_live_..."Response:
{
"data": [
{
"id": "cat_abc123",
"name": "E-Bikes",
"slug": "e-bikes",
"description": "Electric mountain and trail bikes",
"image_url": "https://storage.getrenta.io/...",
"sort_order": 1
}
],
"has_more": false,
"next_cursor": null
}Get Category
GET /v1/fleet/categories/:idconst category = await renta.fleet.categories.get('cat_abc123');curl https://api.getrenta.io/v1/fleet/categories/cat_abc123 \
-H "Authorization: Bearer renta_sk_live_..."Create Category
POST /v1/fleet/categoriesBody Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Category display name |
slug | string | ✅ | URL-friendly identifier |
description | string | — | Category description |
image_url | string | — | Category image URL |
sort_order | integer | — | Display order (default 0) |
const category = await renta.fleet.categories.create({
name: 'E-Bikes',
slug: 'e-bikes',
description: 'Electric mountain and trail bikes',
});curl -X POST https://api.getrenta.io/v1/fleet/categories \
-H "Authorization: Bearer renta_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "E-Bikes",
"slug": "e-bikes",
"description": "Electric mountain and trail bikes"
}'Update Category
PATCH /v1/fleet/categories/:idawait renta.fleet.categories.update('cat_abc123', {
name: 'Electric Bikes',
});curl -X PATCH https://api.getrenta.io/v1/fleet/categories/cat_abc123 \
-H "Authorization: Bearer renta_sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "Electric Bikes"}'Delete Category
DELETE /v1/fleet/categories/:idawait renta.fleet.categories.del('cat_abc123');curl -X DELETE https://api.getrenta.io/v1/fleet/categories/cat_abc123 \
-H "Authorization: Bearer renta_sk_live_..."Items
List Items
GET /v1/fleet/itemsList fleet items with filtering, sorting, and cursor-based pagination.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
category_id | string | Filter by category |
status | string | Filter by status: available, maintenance, retired |
query | string | Search by name or description |
skill_level | string | Filter by skill level |
min_price | integer | Minimum full-day price (cents) |
max_price | integer | Maximum full-day price (cents) |
sort | string | Sort field: name, price_full_day, sort_order, created_at |
order | string | Sort direction: asc (default) or desc |
cursor | string | Pagination cursor |
limit | integer | Results per page (1–100, default 20) |
Publishable keys automatically filter to status: available. Secret keys can see all statuses.
// List all available items
const items = await renta.fleet.items.list({
status: 'available',
});
// Search with filters
const bikes = await renta.fleet.items.list({
category_id: 'cat_abc123',
query: 'trail',
sort: 'price_full_day',
order: 'asc',
});
// Auto-paginate through all items
for await (const item of renta.fleet.items.list()) {
console.log(item.name);
}curl "https://api.getrenta.io/v1/fleet/items?status=available&category_id=cat_abc123&sort=price_full_day" \
-H "Authorization: Bearer renta_sk_live_..."Response:
{
"data": [
{
"id": "fi_abc123",
"category_id": "cat_xyz",
"name": "Trail Blazer 500",
"slug": "trail-blazer-500",
"description": "High-performance electric mountain bike",
"skill_level": "intermediate",
"status": "available",
"photos": [
{"url": "https://storage.getrenta.io/..."}
],
"price_half_day": 3500,
"price_full_day": 5000,
"price_multi_day": 4000,
"price_weekly": 25000,
"deposit_amount": 15000,
"live": true,
"sku": "TB-500",
"specs": { "weight": "22kg", "motor": "750W" },
"inventory_count": 3,
"category": {
"id": "cat_xyz",
"name": "E-Bikes",
"slug": "e-bikes"
},
"sort_order": 1,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z"
}
],
"has_more": true,
"next_cursor": "eyJpZCI6ImZpXzk5OSJ9"
}The fields live, sku, specs, and inventory_count are returned for all key types. Secret keys also receive admin-only fields like deposit_hold_timing, deposit_hold_duration, deposit_auto_release, min_duration, max_duration, buffer_hours, same_day_booking, notice_hours, inspection_required, meta_title, and units_in_maintenance.
Get Item
GET /v1/fleet/items/:idconst item = await renta.fleet.items.get('fi_abc123');
console.log(item.name); // "Trail Blazer 500"curl https://api.getrenta.io/v1/fleet/items/fi_abc123 \
-H "Authorization: Bearer renta_sk_live_..."Create Item
POST /v1/fleet/itemsBody Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id | string | ✅ | Parent category ID |
name | string | ✅ | Item display name |
slug | string | ✅ | URL-friendly identifier |
description | string | — | Item description |
skill_level | string | — | Skill level required |
price_half_day | integer | ✅ | Half-day price in cents |
price_full_day | integer | ✅ | Full-day price in cents |
price_multi_day | integer | — | Multi-day rate in cents |
price_weekly | integer | — | Weekly rate in cents |
deposit_amount | integer | — | Deposit amount in cents |
deposit_hold_timing | string | — | at_booking or at_pickup |
deposit_hold_duration | string | — | until_return or custom hours |
deposit_auto_release | boolean | — | Auto-release deposit on return (default true) |
min_duration | integer | — | Minimum rental days |
max_duration | integer | — | Maximum rental days |
buffer_hours | integer | — | Buffer between rentals in hours |
same_day_booking | boolean | — | Allow same-day bookings (default true) |
notice_hours | integer | — | Required advance notice in hours |
photos | array | — | Array of {url: string} objects |
live | boolean | — | Whether item is live/published (default false) |
sku | string | — | Stock keeping unit identifier |
specs | object | — | Free-form specifications object |
inventory_count | integer | — | Number of units available (default 1) |
sort_order | integer | — | Display order |
const item = await renta.fleet.items.create({
category_id: 'cat_abc123',
name: 'Trail Blazer 500',
slug: 'trail-blazer-500',
price_half_day: 3500,
price_full_day: 5000,
price_multi_day: 4000,
price_weekly: 25000,
deposit_amount: 15000,
buffer_hours: 2,
});curl -X POST https://api.getrenta.io/v1/fleet/items \
-H "Authorization: Bearer renta_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"category_id": "cat_abc123",
"name": "Trail Blazer 500",
"slug": "trail-blazer-500",
"price_half_day": 3500,
"price_full_day": 5000,
"deposit_amount": 15000
}'Update Item
PATCH /v1/fleet/items/:idAccepts any subset of the create parameters.
await renta.fleet.items.update('fi_abc123', {
status: 'maintenance',
price_full_day: 5500,
});curl -X PATCH https://api.getrenta.io/v1/fleet/items/fi_abc123 \
-H "Authorization: Bearer renta_sk_live_..." \
-H "Content-Type: application/json" \
-d '{"status": "maintenance", "price_full_day": 5500}'Delete Item
DELETE /v1/fleet/items/:idSoft-deletes the item by setting status to retired. Items with active bookings cannot be deleted (returns 409 Conflict).
await renta.fleet.items.del('fi_abc123');curl -X DELETE https://api.getrenta.io/v1/fleet/items/fi_abc123 \
-H "Authorization: Bearer renta_sk_live_..."Response:
{
"deleted": true,
"id": "fi_abc123"
}Photos
Photo endpoints require a secret key (renta_sk_). Publishable keys will receive a 403 Forbidden error.
Upload Photo
POST /v1/fleet/photosUpload a fleet photo via multipart form data. The image is stored in Supabase Storage and a public URL is returned.
Body (multipart/form-data):
| Parameter | Type | Required | Description |
|---|---|---|---|
file | File | ✅ | Image file (JPEG, PNG, WebP, or GIF). Max 10 MB. |
import { readFileSync } from 'fs';
const buffer = readFileSync('./photo.jpg');
const file = new Blob([buffer], { type: 'image/jpeg' });
const result = await renta.fleet.photos.upload(file, 'photo.jpg');
console.log(result.url); // public URL
console.log(result.path); // storage path (use for deletion)curl -X POST https://api.getrenta.io/v1/fleet/photos \
-H "Authorization: Bearer renta_sk_live_..." \
-F "file=@photo.jpg"Response (201):
{
"url": "https://storage.getrenta.io/fleet-photos/tenant_abc/1717200000-a1b2c3.jpg",
"path": "tenant_abc/1717200000-a1b2c3.jpg"
}Delete Photo
DELETE /v1/fleet/photosDelete a fleet photo by its storage path.
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
path | string | ✅ | Storage path returned from the upload endpoint |
const result = await renta.fleet.photos.delete(
'tenant_abc/1717200000-a1b2c3.jpg'
);
console.log(result.deleted); // truecurl -X DELETE https://api.getrenta.io/v1/fleet/photos \
-H "Authorization: Bearer renta_sk_live_..." \
-H "Content-Type: application/json" \
-d '{"path": "tenant_abc/1717200000-a1b2c3.jpg"}'Response:
{
"deleted": true,
"path": "tenant_abc/1717200000-a1b2c3.jpg"
}