# Repull — Full Documentation for LLMs > This file contains the complete Repull API documentation in a format optimized for LLMs. > For the summary version, see /llms.txt > For AI agent discovery, see /.well-known/agents.json > Base URL: https://api.repull.dev > Docs: https://repull.dev/docs > OpenAPI: https://api.repull.dev/openapi.json > Updated: 2026-04-05 ## Table of Contents 1. Introduction 2. Authentication (complete guide) 3. Properties API 4. Reservations API 5. Availability API 6. Conversations API 7. Reviews API 8. Channel Manager — Airbnb 9. Channel Manager — Booking.com 10. Channel Manager — VRBO 11. Channel Manager — Plumguide 12. Connections API 13. AI Operations 14. Webhooks (all events + payload examples) 15. Billing 16. Error Handling 17. SDKs & Tools (TypeScript, Python, MCP, CLI) 18. PMS Connection Guides (per-platform) 19. Rate Limits 20. Changelog --- ## 1. Introduction Repull is the unified API for vacation rental technology. One API key connects to 50+ PMS platforms and 4 OTA channels: **Verified PMS platforms (21):** Hostaway, Guesty, OwnerRez, Smoobu, Beds24, iGMS, Hospitable, Lodgify, BookingSync, Cloudbeds, Hostfully, Mews, Tokeet, Streamline, Zeevou, Uplisting, Hostify, Avantio, Apaleo, Escapia, Amenitiz **OTA channels (4):** Airbnb, Booking.com, VRBO, Plumguide **Key capabilities:** - Pull normalized property, reservation, availability, conversation, and review data from any PMS - Push listings, pricing, availability, and messages TO Airbnb and Booking.com - AI operations for guest communication, listing optimization, pricing, and review management - Webhook delivery for real-time event notifications - Calry-compatible schema for easy migration --- ## 2. Authentication (Complete Guide) ### Required Headers Every API request MUST include: ``` Authorization: Bearer YOUR_API_KEY X-Workspace-Id: YOUR_WORKSPACE_UUID ``` ### Optional Headers ``` X-Account-Id: UUID — Scope request to a specific PMS account (required for multi-account workspaces) X-Schema: calry — Response format: "calry" (default), "calry-v1", "native" Idempotency-Key: UUID — For POST/PUT/PATCH requests to prevent duplicate operations ``` ### API Key Types | Prefix | Mode | Description | |--------|------|-------------| | `sk_test_*` | Sandbox | Pre-seeded fake data. No rate limits. No side effects. Safe for development. | | `sk_live_*` | Live | Real PMS/OTA data. Rate limited. Actions are real (messages send, reservations create). | ### Getting API Keys 1. Sign up at https://repull.dev 2. Create a workspace 3. Go to Settings > API Keys 4. Copy your sandbox key (starts with `sk_test_`) ### Authentication Examples **curl:** ```bash curl -H "Authorization: Bearer sk_test_abc123" \ -H "X-Workspace-Id: ws_def456" \ https://api.repull.dev/v1/properties ``` **TypeScript:** ```typescript import { Repull } from '@repull/sdk' const repull = new Repull({ apiKey: 'sk_test_abc123', workspaceId: 'ws_def456', }) ``` **Python:** ```python from repull import Repull client = Repull(api_key="sk_test_abc123", workspace_id="ws_def456") ``` **fetch (browser/Node):** ```javascript const res = await fetch('https://api.repull.dev/v1/properties', { headers: { 'Authorization': 'Bearer sk_test_abc123', 'X-Workspace-Id': 'ws_def456', }, }) const data = await res.json() ``` --- ## 3. Properties API ### List Properties ``` GET /v1/properties ``` Query parameters: | Param | Type | Default | Description | |-------|------|---------|-------------| | limit | number | 50 | Max results (1-200) | | offset | number | 0 | Pagination offset | | status | string | "active" | Filter: active, inactive, all | Response: ```json { "data": [ { "id": 6248, "name": "Oceanview Villa", "address": "123 Coast Hwy", "city": "Malibu", "state": "CA", "country": "US", "zipCode": "90265", "latitude": 34.0259, "longitude": -118.7798, "bedrooms": 3, "bathrooms": 2, "maxGuests": 8, "propertyType": "villa", "status": "active", "currency": "USD", "timezone": "America/Los_Angeles", "images": ["https://..."], "amenities": ["wifi", "pool", "parking", "kitchen"], "platform": "hostaway", "platformId": "HA-6248", "createdAt": "2025-01-15T10:00:00Z", "updatedAt": "2026-04-01T08:30:00Z" } ], "pagination": { "total": 10, "limit": 50, "offset": 0 } } ``` ### Get Single Property ``` GET /v1/properties/:id ``` Returns the same property object as above, but for a single property. --- ## 4. Reservations API ### List Reservations ``` GET /v1/reservations ``` Query parameters: | Param | Type | Default | Description | |-------|------|---------|-------------| | limit | number | 50 | Max results (1-200) | | offset | number | 0 | Pagination offset | | status | string | all | Filter: confirmed, cancelled, pending, checked_in, checked_out | | platform | string | all | Filter by source: airbnb, booking, vrbo, direct, hostaway, etc. | | listing_id | number | — | Filter by property ID | | check_in_after | date | — | ISO date, only reservations checking in after this date | | check_in_before | date | — | ISO date, only reservations checking in before this date | | check_out_after | date | — | ISO date | | check_out_before | date | — | ISO date | | created_after | date | — | ISO date, filter by creation time | Response: ```json { "data": [ { "id": "215906", "listingId": 6250, "checkIn": "2026-06-01", "checkOut": "2026-06-05", "nights": 4, "status": "confirmed", "platform": "airbnb", "totalPrice": "1250.00", "currency": "USD", "confirmationCode": "HMA1234567", "guestName": "Sarah Chen", "guestEmail": "sarah@example.com", "guestPhone": "+1-555-0123", "adults": 2, "children": 1, "infants": 0, "pets": 0, "specialRequests": "Late check-in around 10pm", "createdAt": "2026-03-15T14:00:00Z", "updatedAt": "2026-03-15T14:00:00Z" } ], "pagination": { "total": 42, "limit": 50, "offset": 0 } } ``` ### Create Reservation ``` POST /v1/reservations Content-Type: application/json ``` Body: ```json { "listingId": 6250, "checkIn": "2026-07-01", "checkOut": "2026-07-05", "guestName": "John Doe", "guestEmail": "john@example.com", "guestPhone": "+1-555-0456", "adults": 2, "children": 0, "totalPrice": "1000.00", "currency": "USD", "source": "direct" } ``` ### Update Reservation ``` PATCH /v1/reservations/:id Content-Type: application/json ``` Body (partial update): ```json { "checkIn": "2026-07-02", "checkOut": "2026-07-06", "specialRequests": "Need parking spot" } ``` --- ## 5. Availability API ### Get Availability ``` GET /v1/availability ``` Query parameters: | Param | Type | Required | Description | |-------|------|----------|-------------| | property_id | number | yes | Property ID | | start_date | date | yes | ISO date | | end_date | date | yes | ISO date | Response: ```json { "data": [ { "date": "2026-06-01", "available": true, "price": 250.00, "minNights": 2, "maxNights": 30, "closedToArrival": false, "closedToDeparture": false }, { "date": "2026-06-02", "available": false, "price": 250.00, "reservationId": "215906" } ] } ``` ### Update Availability ``` PUT /v1/availability Content-Type: application/json ``` Body: ```json { "propertyId": "123", "updates": [ { "date": "2026-06-01", "available": true, "price": 250.00, "minNights": 2 }, { "date": "2026-06-02", "available": false }, { "date": "2026-06-03", "available": true, "price": 300.00, "minNights": 3, "maxNights": 14 } ] } ``` --- ## 6. Conversations API ### List Conversations ``` GET /v1/conversations ``` Query parameters: | Param | Type | Default | Description | |-------|------|---------|-------------| | limit | number | 50 | Max results | | offset | number | 0 | Pagination | | platform | string | all | Filter by platform | | reservation_id | string | — | Filter by reservation | Response: ```json { "data": [ { "id": "conv_abc123", "reservationId": "215906", "platform": "airbnb", "guestName": "Sarah Chen", "lastMessage": "What time is check-in?", "lastMessageAt": "2026-04-04T15:30:00Z", "unread": true, "messages": [ { "id": "msg_001", "sender": "guest", "text": "What time is check-in?", "timestamp": "2026-04-04T15:30:00Z" } ] } ], "pagination": { "total": 12, "limit": 50, "offset": 0 } } ``` ### Send Message ``` POST /v1/conversations/:id/messages Content-Type: application/json ``` Body: ```json { "message": "Check-in is at 3pm. I'll send you the access code the day before!", "platform": "airbnb" } ``` --- ## 7. Reviews API ### List Reviews ``` GET /v1/reviews ``` Query parameters: | Param | Type | Default | Description | |-------|------|---------|-------------| | limit | number | 50 | Max results | | offset | number | 0 | Pagination | | platform | string | all | Filter by platform | | listing_id | number | — | Filter by property | | rating_min | number | — | Minimum star rating (1-5) | | responded | boolean | — | Filter by response status | ### Reply to Review ``` POST /v1/reviews/:id/reply Content-Type: application/json ``` Body: ```json { "reply": "Thank you for your wonderful review, Sarah! We loved hosting you." } ``` --- ## 8. Channel Manager — Airbnb Full write access to Airbnb listings, pricing, availability, messaging, reservations, and reviews. ### Create Listing ``` POST /v1/channels/airbnb/listings ``` Body: ```json { "listingId": 123, "hostId": "380436627" } ``` Creates an Airbnb listing draft from your Repull property data. ### Listing Actions ``` POST /v1/channels/airbnb/listings/:id ``` Body: ```json { "action": "push", "connectionId": 456 } ``` Actions: `push` (sync to Airbnb), `pull` (sync from Airbnb), `publish` (go live), `unlist` (hide), `delete` (remove) ### Upload Photos ``` POST /v1/channels/airbnb/listings/:id/photos ``` Body: ```json { "photos": [ { "url": "https://cdn.example.com/living-room.jpg", "caption": "Spacious living room with ocean view" }, { "url": "https://cdn.example.com/bedroom.jpg", "caption": "Master bedroom" } ] } ``` ### Update Pricing ``` PUT /v1/channels/airbnb/listings/:id/pricing ``` Body: ```json { "type": "standard", "settings": { "default_daily_price": 250, "weekend_price": 300, "weekly_discount": 10, "monthly_discount": 20, "currency": "USD" } } ``` Pricing types: `model`, `standard`, `los` (length of stay), `rate-plan`, `fees`, `currency`, `rule`, `calendar` ### Push Availability ``` PUT /v1/channels/airbnb/listings/:id/availability ``` Body: ```json { "type": "calendar", "dates": [ { "date": "2026-06-01", "price": 300, "available": true, "minNights": 2 }, { "date": "2026-06-02", "price": 300, "available": false }, { "date": "2026-06-03", "price": 350, "available": true, "minNights": 3 } ] } ``` ### Send Message ``` POST /v1/channels/airbnb/messaging/:threadId/messages ``` Body: ```json { "message": "Welcome! Here are your check-in instructions..." } ``` ### Reservation Actions ``` POST /v1/channels/airbnb/reservations/:confirmationCode ``` Body: ```json { "action": "accept" } ``` Actions: `accept`, `decline`, `cancel` ### Review Operations ``` POST /v1/channels/airbnb/reviews ``` Body: ```json { "reservationCode": "HMA1234567", "type": "respond", "response": "Thank you for staying with us!" } ``` Types: `respond` (reply to guest review), `submit` (submit host review of guest) ### Special Offers ``` POST /v1/channels/airbnb/offers ``` Body: ```json { "threadId": "thread_123", "type": "special_offer", "listingId": 123, "checkIn": "2026-06-01", "checkOut": "2026-06-05", "price": 1100.00 } ``` Types: `special_offer`, `pre_approval` ### Bulk Sync ``` POST /v1/channels/airbnb/sync ``` Body: ```json { "listingIds": [123, 456] } ``` Omit `listingIds` to sync all connected listings. --- ## 9. Channel Manager — Booking.com Full write access to Booking.com properties, content, rates, availability, and messaging. ### Create Property ``` POST /v1/channels/booking/properties ``` Body: ```json { "listingId": 123 } ``` ### Property Actions ``` POST /v1/channels/booking/properties/:id ``` Body: ```json { "action": "push" } ``` Actions: `push`, `pull`, `unlist`, `relist`, `create-room`, `add-unit` ### Update Content ``` POST /v1/channels/booking/content ``` **Photos:** ```json { "type": "photos", "property_id": 123, "photos": [ { "url": "https://...", "tag": "property_building", "sort_order": 1 } ] } ``` **Descriptions:** ```json { "type": "descriptions", "property_id": 123, "descriptions": { "headline": "Luxury Beachfront Villa", "description": "A stunning 3-bedroom villa..." } } ``` **Amenities:** ```json { "type": "amenities", "property_id": 123, "amenities": ["wifi", "parking", "pool", "air_conditioning"] } ``` Content types: `photos`, `descriptions`, `amenities`, `facilities`, `policies` ### Update Rates and Availability ``` PUT /v1/channels/booking/availability ``` **Rates:** ```json { "type": "rates", "updates": [ { "roomId": "room_123", "ratePlanId": "rate_456", "dateFrom": "2026-06-01", "dateTo": "2026-06-30", "price": 250.00, "currency": "USD" } ] } ``` **Availability:** ```json { "type": "availability", "updates": [ { "roomId": "room_123", "dateFrom": "2026-06-01", "dateTo": "2026-06-30", "available": 1, "minStay": 2, "maxStay": 14, "closedToArrival": false, "closedToDeparture": false } ] } ``` **Derived Pricing:** ```json { "type": "derived-pricing", "updates": [ { "parentRatePlanId": "rate_456", "derivedRatePlanId": "rate_789", "adjustment": -10, "adjustmentType": "percentage" } ] } ``` Types: `rates`, `availability`, `derived-pricing` ### Send Message ``` POST /v1/channels/booking/messaging ``` Body: ```json { "reservationId": "BK-123456", "message": "Welcome to our property..." } ``` ### Setup & Go Live ``` POST /v1/channels/booking/setup ``` **Create Legal Entity:** ```json { "action": "create-legal-entity", "property_id": 123, "legalEntity": { "name": "Vacation Rentals LLC", "type": "company", "country": "US" } } ``` **Check Readiness:** ```json { "action": "check-readiness", "property_id": 123 } ``` **Open Property (Go Live):** ```json { "action": "open-property", "property_id": 123 } ``` **Set Contacts:** ```json { "action": "set-contacts", "property_id": 123, "contacts": { "email": "host@example.com", "phone": "+1-555-0123" } } ``` Actions: `create-legal-entity`, `check-readiness`, `open-property`, `set-contacts` ### Bulk Sync ``` POST /v1/channels/booking/sync ``` Body: ```json { "propertyIds": [123, 456] } ``` --- ## 10. Channel Manager — VRBO VRBO uses an agency model — VRBO pushes data to Repull endpoints. Read-only API. ### List Listings ``` GET /v1/channels/vrbo/listings ``` ### List Reservations ``` GET /v1/channels/vrbo/reservations ``` Query parameters: `limit`, `offset`, `status`, `check_in_after`, `check_in_before` --- ## 11. Channel Manager — Plumguide ### List Listings ``` GET /v1/channels/plumguide/listings ``` ### Push Availability ``` PUT /v1/channels/plumguide/availability ``` Body: ```json { "listingId": "pg_123", "dates": [ { "date": "2026-06-01", "available": true }, { "date": "2026-06-02", "available": false } ] } ``` ### Push Pricing ``` PUT /v1/channels/plumguide/pricing ``` Body: ```json { "listingId": "pg_123", "seasons": [ { "startDate": "2026-06-01", "endDate": "2026-08-31", "nightlyRate": 350.00, "currency": "USD" } ] } ``` ### List Bookings ``` GET /v1/channels/plumguide/bookings ``` --- ## 12. Connections API ### List All Connections ``` GET /v1/connect ``` Response: ```json { "data": [ { "provider": "hostaway", "status": "connected", "accountId": "acc_123", "accountName": "My Hostaway Account", "propertiesCount": 15, "lastSyncAt": "2026-04-04T12:00:00Z", "connectedAt": "2025-06-15T10:00:00Z" } ] } ``` ### Get Connection Status ``` GET /v1/connect/:provider ``` ### Connect to Provider ``` POST /v1/connect/:provider Content-Type: application/json ``` **OAuth providers (Hostaway, Guesty, Beds24, Lodgify, BookingSync, Cloudbeds, Mews, Apaleo):** ```json { "type": "oauth", "redirectUrl": "https://your-app.com/callback" } ``` Returns `{ "authorizationUrl": "https://..." }` — redirect user there. **Credential providers (OwnerRez, Smoobu, iGMS, Hospitable, Hostfully, Tokeet, Streamline, Zeevou, Uplisting, Hostify, Avantio, Escapia, Amenitiz):** ```json { "type": "credentials", "credentials": { "apiKey": "their_pms_api_key", "accountId": "their_account_id" } } ``` ### Disconnect ``` DELETE /v1/connect/:provider ``` ### Supported Providers Full list: `airbnb`, `booking`, `vrbo`, `plumguide`, `hostaway`, `guesty`, `ownerrez`, `smoobu`, `beds24`, `igms`, `hospitable`, `lodgify`, `bookingsync`, `cloudbeds`, `hostfully`, `mews`, `tokeet`, `streamline`, `zeevou`, `uplisting`, `hostify`, `avantio`, `apaleo`, `escapia`, `amenitiz` --- ## 13. AI Operations Unified endpoint for all AI capabilities. ``` POST /v1/ai Content-Type: application/json ``` ### Chat (Natural Language Queries) ```json { "action": "chat", "query": "What's my occupancy rate for June?", "context": { "listingId": 123 }, "stream": false } ``` Response: ```json { "action": "chat", "response": "Your occupancy rate for June is 78%. You have 7 nights available..." } ``` ### Respond to Guest ```json { "action": "respond-to-guest", "query": "Guest asks: Is there a pool?", "context": { "listingId": 123, "reservationId": "215906", "conversationHistory": [ { "sender": "guest", "text": "Hi, does the property have a pool?" } ] } } ``` Response: ```json { "action": "respond-to-guest", "response": "Yes! We have a heated outdoor pool available from 8am-10pm...", "confidence": 0.95, "sources": ["property_amenities", "house_rules"] } ``` ### Classify Intent ```json { "action": "classify-intent", "query": "The hot water isn't working", "context": { "reservationId": "215906" } } ``` Response: ```json { "action": "classify-intent", "intent": "maintenance_request", "confidence": 0.92, "subIntents": ["plumbing", "urgent"] } ``` Intent categories: `inquiry`, `booking_request`, `complaint`, `maintenance_request`, `check_in_info`, `check_out_info`, `cancellation`, `modification`, `payment`, `review`, `spam`, `other` ### Generate Listing ```json { "action": "generate-listing", "context": { "listingId": 123, "style": "professional", "highlights": ["ocean view", "newly renovated", "walk to beach"] } } ``` Response: ```json { "action": "generate-listing", "title": "Stunning Oceanview Villa — Steps from the Beach", "description": "Wake up to panoramic ocean views in this newly renovated...", "highlights": ["Panoramic ocean views from every room", "2-minute walk to the beach", ...] } ``` ### Review Response ```json { "action": "review-response", "query": "Guest left a 3-star review about noise from construction nearby", "context": { "reviewText": "Nice place but construction noise was terrible...", "rating": 3, "listingId": 123 } } ``` ### Price Suggestion ```json { "action": "price-suggestion", "context": { "listingId": 123, "dateRange": { "start": "2026-06-01", "end": "2026-06-30" }, "currentPrice": 250.00 } } ``` Response: ```json { "action": "price-suggestion", "suggestions": [ { "date": "2026-06-01", "suggestedPrice": 280.00, "reason": "High demand weekend" }, { "date": "2026-06-15", "suggestedPrice": 220.00, "reason": "Midweek low demand" } ], "averageSuggested": 255.00, "marketComparison": "12% above comparable properties" } ``` --- ## 14. Webhooks ### Create Subscription ``` POST /v1/webhooks Content-Type: application/json ``` Body: ```json { "url": "https://your-app.com/webhooks/repull", "events": ["reservation.created", "reservation.updated", "reservation.cancelled"], "secret": "whsec_optional_signing_secret" } ``` Response: ```json { "id": "wh_abc123", "url": "https://your-app.com/webhooks/repull", "events": ["reservation.created", "reservation.updated", "reservation.cancelled"], "active": true, "createdAt": "2026-04-04T12:00:00Z" } ``` ### List Subscriptions ``` GET /v1/webhooks ``` ### Delete Subscription ``` DELETE /v1/webhooks/:id ``` ### All Webhook Events **reservation.created** — New booking from any platform ```json { "event": "reservation.created", "timestamp": "2026-04-04T12:00:00Z", "webhookId": "wh_abc123", "data": { "id": "215906", "listingId": 6250, "platform": "airbnb", "confirmationCode": "HMA1234567", "status": "confirmed", "checkIn": "2026-06-01", "checkOut": "2026-06-05", "guestName": "Sarah Chen", "totalPrice": "1250.00", "currency": "USD" } } ``` **reservation.updated** — Dates, status, or details changed ```json { "event": "reservation.updated", "timestamp": "2026-04-04T14:00:00Z", "webhookId": "wh_abc123", "data": { "id": "215906", "listingId": 6250, "platform": "airbnb", "status": "confirmed", "checkIn": "2026-06-02", "checkOut": "2026-06-06", "changes": ["checkIn", "checkOut"] } } ``` **reservation.cancelled** — Booking cancelled ```json { "event": "reservation.cancelled", "timestamp": "2026-04-04T16:00:00Z", "webhookId": "wh_abc123", "data": { "id": "215906", "listingId": 6250, "platform": "airbnb", "status": "cancelled", "cancelledBy": "guest", "cancellationReason": "Change of plans" } } ``` **conversation.updated** — New guest message ```json { "event": "conversation.updated", "timestamp": "2026-04-04T15:30:00Z", "webhookId": "wh_abc123", "data": { "conversationId": "conv_abc123", "reservationId": "215906", "platform": "airbnb", "lastMessage": { "sender": "guest", "text": "What time is check-in?", "timestamp": "2026-04-04T15:30:00Z" } } } ``` **sync.complete** — PMS/OTA sync finished ```json { "event": "sync.complete", "timestamp": "2026-04-04T12:05:00Z", "webhookId": "wh_abc123", "data": { "provider": "hostaway", "accountId": "acc_123", "propertiesSynced": 15, "reservationsSynced": 42, "duration": 12500 } } ``` **sync.error** — Sync failed ```json { "event": "sync.error", "timestamp": "2026-04-04T12:05:00Z", "webhookId": "wh_abc123", "data": { "provider": "hostaway", "accountId": "acc_123", "error": "Authentication expired. Please reconnect.", "code": "auth_expired" } } ``` **account.connected** — New PMS/OTA connected ```json { "event": "account.connected", "timestamp": "2026-04-04T10:00:00Z", "webhookId": "wh_abc123", "data": { "provider": "guesty", "accountId": "acc_456", "accountName": "My Properties", "propertiesCount": 8 } } ``` **account.disconnected** — PMS/OTA disconnected ```json { "event": "account.disconnected", "timestamp": "2026-04-04T18:00:00Z", "webhookId": "wh_abc123", "data": { "provider": "guesty", "accountId": "acc_456", "reason": "user_initiated" } } ``` ### Webhook Signature Verification If you provide a `secret` when creating the webhook, Repull signs payloads with HMAC-SHA256: ``` X-Repull-Signature: sha256=HMAC_HEX_DIGEST X-Repull-Timestamp: 1712232000 ``` Verification (Node.js): ```javascript const crypto = require('crypto') function verifyWebhook(payload, signature, timestamp, secret) { const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}.${payload}`) .digest('hex') return `sha256=${expected}` === signature } ``` --- ## 15. Billing ### Get Current Plan ``` GET /v1/billing ``` Response: ```json { "plan": "professional", "interval": "month", "usage": { "apiCalls": 12500, "apiCallsLimit": 100000, "properties": 25, "propertiesLimit": 100, "channels": 3, "channelsLimit": 4 }, "currentPeriodEnd": "2026-05-01T00:00:00Z" } ``` ### Create Checkout Session ``` POST /v1/billing Content-Type: application/json ``` Body: ```json { "tier": "professional", "interval": "month" } ``` Tiers: `essentials`, `professional`, `scale` Returns: ```json { "checkoutUrl": "https://checkout.stripe.com/..." } ``` --- ## 16. Error Handling All errors follow a consistent format: ```json { "error": { "code": "not_found", "message": "Property with ID 999 not found.", "docs_url": "https://repull.dev/docs/properties", "example": "curl -H 'Authorization: Bearer sk_test_KEY' https://api.repull.dev/v1/properties" } } ``` ### Error Codes | HTTP | Code | Description | |------|------|-------------| | 400 | `bad_request` | Invalid request body or parameters | | 401 | `unauthorized` | Missing or invalid API key | | 403 | `forbidden` | API key lacks permission for this action | | 404 | `not_found` | Resource not found | | 409 | `conflict` | Duplicate operation (use Idempotency-Key) | | 422 | `validation_error` | Request body failed validation | | 429 | `rate_limited` | Too many requests | | 500 | `internal_error` | Server error (retry with backoff) | | 502 | `upstream_error` | PMS/OTA provider returned an error | | 503 | `provider_unavailable` | PMS/OTA provider is down | ### Rate Limit Headers ``` X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 950 X-RateLimit-Reset: 1712232000 ``` --- ## 17. SDKs & Tools ### TypeScript SDK ```bash npm install @repull/sdk ``` Full example: ```typescript import { Repull } from '@repull/sdk' const repull = new Repull({ apiKey: process.env.REPULL_API_KEY!, workspaceId: process.env.REPULL_WORKSPACE_ID!, }) // Properties const properties = await repull.properties.list() const property = await repull.properties.get(6248) // Reservations const reservations = await repull.reservations.list({ status: 'confirmed', checkInAfter: '2026-06-01', }) const newRes = await repull.reservations.create({ listingId: 6248, checkIn: '2026-07-01', checkOut: '2026-07-05', guestName: 'John Doe', guestEmail: 'john@example.com', adults: 2, totalPrice: '1000.00', currency: 'USD', }) // Availability const calendar = await repull.availability.get({ propertyId: 6248, startDate: '2026-06-01', endDate: '2026-06-30', }) await repull.availability.update({ propertyId: '6248', updates: [{ date: '2026-06-01', available: true, price: 250.00 }], }) // Conversations const conversations = await repull.conversations.list() await repull.conversations.sendMessage('conv_abc123', { message: 'Check-in is at 3pm!', }) // Airbnb Channel await repull.channels.airbnb.createListing({ listingId: 123, hostId: '380436627' }) await repull.channels.airbnb.pushAvailability(123, { type: 'calendar', dates: [{ date: '2026-06-01', price: 300, available: true }], }) await repull.channels.airbnb.updatePricing(123, { type: 'standard', settings: { default_daily_price: 250 }, }) await repull.channels.airbnb.sendMessage('thread_123', { message: 'Welcome!' }) await repull.channels.airbnb.sync() // Booking.com Channel await repull.channels.booking.createProperty({ listingId: 123 }) await repull.channels.booking.updateAvailability({ type: 'rates', updates: [{ roomId: 'room_123', dateFrom: '2026-06-01', dateTo: '2026-06-30', price: 250.00 }], }) // AI Operations const aiReply = await repull.ai.respondToGuest('Guest asks about WiFi password', { listingId: 123, reservationId: '215906', }) const intent = await repull.ai.classifyIntent('The hot water is broken') const listing = await repull.ai.generateListing({ listingId: 123, style: 'professional' }) const prices = await repull.ai.priceSuggestion({ listingId: 123, dateRange: { start: '2026-06-01', end: '2026-06-30' }, }) // Connections const connections = await repull.connect.list() await repull.connect.connect('hostaway', { type: 'oauth', redirectUrl: 'https://your-app.com/callback', }) // Webhooks await repull.webhooks.create({ url: 'https://your-app.com/webhooks', events: ['reservation.created', 'reservation.updated'], }) ``` ### Python SDK ```bash pip install repull ``` Full example: ```python from repull import Repull client = Repull(api_key="sk_test_KEY", workspace_id="WS_ID") # Properties properties = client.properties.list() prop = client.properties.get(6248) # Reservations reservations = client.reservations.list(status="confirmed", check_in_after="2026-06-01") new_res = client.reservations.create( listing_id=6248, check_in="2026-07-01", check_out="2026-07-05", guest_name="John Doe", guest_email="john@example.com", adults=2, total_price="1000.00", currency="USD", ) # Availability calendar = client.availability.get(property_id=6248, start_date="2026-06-01", end_date="2026-06-30") client.availability.update( property_id="6248", updates=[{"date": "2026-06-01", "available": True, "price": 250.00}], ) # Conversations conversations = client.conversations.list() client.conversations.send_message("conv_abc123", message="Check-in is at 3pm!") # Airbnb Channel client.channels.airbnb.create_listing(listing_id=123, host_id="380436627") client.channels.airbnb.push_availability(123, dates=[{"date": "2026-06-01", "price": 300, "available": True}]) client.channels.airbnb.update_pricing(123, type="standard", settings={"default_daily_price": 250}) client.channels.airbnb.send_message("thread_123", message="Welcome!") client.channels.airbnb.sync() # Booking.com Channel client.channels.booking.create_property(listing_id=123) client.channels.booking.update_availability( type="rates", updates=[{"room_id": "room_123", "date_from": "2026-06-01", "date_to": "2026-06-30", "price": 250.00}], ) # AI Operations reply = client.ai.respond_to_guest("Guest asks about WiFi", listing_id=123) intent = client.ai.classify_intent("The hot water is broken") listing = client.ai.generate_listing(listing_id=123, style="professional") prices = client.ai.price_suggestion(listing_id=123, start="2026-06-01", end="2026-06-30") # Connections connections = client.connect.list() auth_url = client.connect.connect("hostaway", type="oauth", redirect_url="https://your-app.com/callback") # Webhooks client.webhooks.create( url="https://your-app.com/webhooks", events=["reservation.created", "reservation.updated"], ) ``` ### MCP Server (for Claude Desktop, Cursor, Windsurf) Install: ```bash npx @repull/mcp-server ``` Add to `claude_desktop_config.json` or `.cursor/mcp.json`: ```json { "mcpServers": { "repull": { "command": "npx", "args": ["@repull/mcp-server"], "env": { "REPULL_API_KEY": "sk_test_YOUR_KEY", "REPULL_WORKSPACE_ID": "YOUR_WS_ID" } } } } ``` **Available tools (18):** 1. `list_properties` — List all properties 2. `get_property` — Get property details 3. `list_reservations` — List reservations with filters 4. `get_reservation` — Get reservation details 5. `create_reservation` — Create a new reservation 6. `update_reservation` — Update reservation details 7. `get_availability` — Get calendar availability 8. `update_availability` — Update dates/prices 9. `list_conversations` — List guest conversations 10. `send_message` — Send message to guest 11. `push_to_airbnb` — Push listing to Airbnb 12. `push_to_booking` — Push listing to Booking.com 13. `sync_channel` — Sync all listings to a channel 14. `ai_respond` — Generate AI guest response 15. `ai_classify` — Classify message intent 16. `ai_generate_listing` — Generate listing content 17. `list_connections` — List PMS/OTA connections 18. `create_webhook` — Set up webhook subscription ### CLI ```bash npm install -g @repull/cli # Authenticate repull login # Properties repull properties list repull properties get 6248 # Reservations repull reservations list --platform airbnb --status confirmed repull reservations create --listing 6248 --check-in 2026-07-01 --check-out 2026-07-05 # Availability repull availability get --property 6248 --start 2026-06-01 --end 2026-06-30 repull availability update --property 6248 --date 2026-06-01 --price 250 --available # Channels repull airbnb push --listing 6248 repull airbnb sync repull booking push --listing 6248 # AI repull ai respond "Guest asks about pool" repull ai classify "The heater is broken" repull ai listing --property 6248 # Connections repull connect list repull connect hostaway --oauth ``` --- ## 18. PMS Connection Guides ### Hostaway **Auth:** OAuth 2.0. Call `POST /v1/connect/hostaway` with `type: "oauth"`, redirect user to returned URL. Hostaway grants API access after user approves. Full property and reservation sync. ### Guesty **Auth:** OAuth 2.0. Call `POST /v1/connect/guesty` with `type: "oauth"`. Supports properties, reservations, conversations, and availability. Real-time webhook sync available. ### OwnerRez **Auth:** API key. Get API key from OwnerRez Settings > API. Pass via `POST /v1/connect/ownerrez` with `type: "credentials"`. Supports properties, reservations, availability, and pricing. ### Smoobu **Auth:** API key. Get from Smoobu Settings > API. Pass via `POST /v1/connect/smoobu`. Supports properties, reservations, and availability. ### Beds24 **Auth:** OAuth 2.0. Call `POST /v1/connect/beds24` with `type: "oauth"`. Full property, reservation, and availability sync. Supports rate plans. ### iGMS **Auth:** API key. Get from iGMS dashboard. Pass via `POST /v1/connect/igms`. Supports properties and reservations. ### Hospitable **Auth:** API key. Get from Hospitable Settings > Integrations. Pass via `POST /v1/connect/hospitable`. Supports properties, reservations, and conversations. ### Lodgify **Auth:** OAuth 2.0. Call `POST /v1/connect/lodgify` with `type: "oauth"`. Supports properties, reservations, availability, and pricing. ### BookingSync **Auth:** OAuth 2.0. Call `POST /v1/connect/bookingsync` with `type: "oauth"`. Supports rentals, bookings, and availability calendars. ### Cloudbeds **Auth:** OAuth 2.0. Call `POST /v1/connect/cloudbeds` with `type: "oauth"`. Supports properties, reservations, availability, and guest profiles. ### Hostfully **Auth:** API key. Get from Hostfully API settings. Pass via `POST /v1/connect/hostfully`. Supports properties and reservations. ### Mews **Auth:** OAuth 2.0. Call `POST /v1/connect/mews` with `type: "oauth"`. Enterprise-grade PMS. Supports spaces, reservations, availability, and rate plans. ### Tokeet **Auth:** API key. Get from Tokeet Settings. Pass via `POST /v1/connect/tokeet`. Supports rentals, reservations, and calendars. ### Streamline **Auth:** API key. Get from Streamline admin panel. Pass via `POST /v1/connect/streamline`. Supports units, reservations, and availability. ### Zeevou **Auth:** API key. Get from Zeevou API settings. Pass via `POST /v1/connect/zeevou`. Supports properties, bookings, and rate management. ### Uplisting **Auth:** API key. Get from Uplisting dashboard. Pass via `POST /v1/connect/uplisting`. Supports listings, reservations, and calendars. ### Hostify **Auth:** API key. Get from Hostify integrations page. Pass via `POST /v1/connect/hostify`. Supports properties and reservations. ### Avantio **Auth:** API key. Get from Avantio back office. Pass via `POST /v1/connect/avantio`. Supports accommodations, bookings, and availability. ### Apaleo **Auth:** OAuth 2.0. Call `POST /v1/connect/apaleo` with `type: "oauth"`. Hotel-focused but supports vacation rental use cases. Full property and reservation sync. ### Escapia **Auth:** API key. Get from Escapia admin. Pass via `POST /v1/connect/escapia`. Supports units, reservations, and pricing. ### Amenitiz **Auth:** API key. Get from Amenitiz Settings > API. Pass via `POST /v1/connect/amenitiz`. Supports properties, reservations, and availability. --- ## 19. Rate Limits | Plan | Requests/minute | Requests/day | |------|-----------------|--------------| | Sandbox (sk_test_*) | Unlimited | Unlimited | | Essentials | 100 | 10,000 | | Professional | 500 | 100,000 | | Scale | 2,000 | 1,000,000 | Rate limit headers are included in every response: ``` X-RateLimit-Limit: 500 X-RateLimit-Remaining: 498 X-RateLimit-Reset: 1712232060 ``` When rate limited (429), retry after the `Retry-After` header value (seconds). --- ## 20. Changelog ### 2026-04-05 - Added agents.json for AI agent discovery - Expanded llms.txt and llms-full.txt for AI coding assistants - 50+ PMS connectors (21 verified, additional scaffolds available) ### 2026-04-04 - Channel Manager: Plumguide bookings endpoint - AI Operations: price-suggestion action - Webhook signature verification ### 2026-04-01 - Initial public API launch - 9 verified PMS connectors - Airbnb and Booking.com channel management - MCP server with 18 tools - TypeScript SDK v1.0