Developers
Examples
Copyable SDK patterns for a rental storefront and a server integration, such as a dated catalog, a booking request form, goods for sale, syncing new bookings, and handling rate limits.
The snippets assume a requiply client from the Quick Start: a publishable key for storefront examples, a secret key for server examples. IDs such as cameraKitId stand for UUIDs you read from the catalog.
Storefront: catalog for chosen dates
const { items, nextCursor } = await requiply.inventory.list({
startDate: '2026-07-01T10:00:00+03:00',
endDate: '2026-07-03T18:00:00+03:00',
limit: 50,
});
for (const item of items) {
console.log(item.name, item.basePrice, item.currency, `${item.availableQuantity} free`);
}
To list only what has at least one unit free for the whole period, use availability.items() with the same dates.
Storefront: offer only valid pickup times
const { workingHours, timezone } = await requiply.org.info();
function isOpen(day: string, time: string) {
const hours = workingHours.find((entry) => entry.day === day);
return !!hours?.isWorkingDay && time >= hours.startTime && time <= hours.endTime;
}
isOpen('saturday', '10:00'); // compare in the organization's timezone
Storefront: booking request form
const result = await requiply.bookings.create({
startDate: '2026-07-01T10:00:00',
endDate: '2026-07-03T18:00:00',
items: [{ groupId: cameraKitId, quantity: 1 }],
deliveryType: 'pickup',
asRequest: true,
client: { name: 'Olena', email: 'olena@example.com', phone: '+380951234567' },
});
if (result.success) {
showThankYou(`Request #${result.reservationOrgId} received`);
} else if (result.reason === 'minimum_duration' && result.minimumDuration) {
const { earliestReturn, timeZone } = result.minimumDuration;
showError(`The earliest return is ${earliestReturn} (${timeZone})`);
} else {
showError(result.message ?? 'These dates cannot be booked');
}
Storefront: add goods for sale
Works only while the organization sells to customers.
import { RequiplyError, type PublicV1SaleItem } from '@requiply/api-sdk';
let goods: PublicV1SaleItem[] = [];
try {
({ items: goods } = await requiply.saleItems.list());
} catch (error) {
if (!(error instanceof RequiplyError && error.reason === 'selling_disabled')) throw error;
}
try {
const quote = await requiply.pricing.quote({
startDate: '2026-07-01T10:00:00',
endDate: '2026-07-03T18:00:00',
items: [{ groupId: cameraKitId, quantity: 1 }],
saleLines: [{ saleItemId: memoryCardId, quantity: 2 }],
});
console.log(quote.saleSubtotal, quote.total);
} catch (error) {
if (error instanceof RequiplyError && error.reason === 'out_of_stock') {
console.log('Only', error.data?.availableQuantity, 'left');
} else {
throw error;
}
}
Server: sync new bookings
let cursor: string | undefined;
do {
const page = await requiply.bookings.list({
createdFrom: lastSyncAt,
limit: 200,
cursor,
});
for (const booking of page.bookings) {
await upsertBooking(booking);
}
cursor = page.nextCursor ?? undefined;
} while (cursor);
Server: find or create a client
const { client, created } = await requiply.clients.create({
name: 'Alex',
email: 'alex@example.com',
});
console.log(created ? 'New client' : 'Existing client', client.id);
clients.create() returns the existing client when the email or phone is already on file, so it is safe to call before every booking.
Cancel a slow quote
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5_000);
try {
const quote = await requiply.pricing.quote(
{
startDate: '2026-07-01T10:00:00',
endDate: '2026-07-03T18:00:00',
items: [{ groupId: cameraKitId, quantity: 1 }],
},
{ signal: controller.signal },
);
console.log(quote.total);
} finally {
clearTimeout(timeout);
}
Handle rate limiting
import { RequiplyError } from '@requiply/api-sdk';
async function withRetry<T>(call: () => Promise<T>): Promise<T> {
try {
return await call();
} catch (error) {
if (error instanceof RequiplyError && error.status === 429) {
const seconds = error.retryAfter ?? 5;
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
return call();
}
throw error;
}
}
const report = await withRetry(() => requiply.reports.pipeline());
Retry reads and quotes freely. Do not wrap bookings.create() or sales.create() this way; see Retries.
Runnable browser examples
For a StackBlitz or similar browser project:
- Depend on a published
@requiply/api-sdkversion and pin it. - Use only a publishable key from a demo organization, and keep it easy to replace.
- Create bookings only as requests with
asRequest: true. - Never include secret-key methods or real customer data.