Update Airbnb Pricing
Push pricing to Airbnb: the pricing model, standard settings, length-of-stay records, rate plans, fees, currency, pricing rules, and per-date calendar operations. All three Airbnb pricing models are supported: Standard, Length of stay, and Rate plan.
/v1/channels/airbnb/listings/:id/pricingParameters
idpathRequiredThe Repull listing id (not the Airbnb listing id).
typestringRequiredWhich pricing sub-resource to write: model | standard | los | rate-plan | fees | currency | rule | calendar. The rest of the body depends on it — see below.
Which endpoint to use
{id}is the Repull listing id — fromGET /v1/propertiesorGET /v1/channels/airbnb/listings— not the Airbnb listing id. Repull translates it before calling Airbnb.- For nightly price, open/closed and min/max nights, the default is
PUT /v1/availability/{propertyId}(orPATCH /v1/availability/batchfor many properties): it writes the Repull calendar and pushes the change to the channels Repull can write a calendar to — Airbnb and Booking.com — in one step. Use this endpoint for settings that exist only on Airbnb. Writes here go to Airbnb alone.
API sync is authorised per listing
Airbnb turns API sync on one listing at a time, not once for the account. Each listing carries its own sync category, and a listing whose category is none is closed to the API — Airbnb refuses every write to it even though the account is connected and every other listing on it writes fine. Reconnecting the Airbnb account does not change a listing's sync category. Only someone with access to the listing on Airbnb can turn sync on for it, on the listing itself.
sync_all— Repull manages content, rates and availability. Every write on this page works.sync_rates_and_availability— Repull manages rates and availability; listing content is managed by the host on Airbnb.none— the listing is not connected to Repull on Airbnb at all. Every write returns403 listing_not_api_connectedand nothing is sent to Airbnb, so nothing is partially applied.- To tell which is which, read
GET /v1/channels/airbnb/listings: every entry of each listing'sconnections[]carriessyncCategory(one of the three above, ornullif it has never been reported) andwritable—falseexactly whensyncCategoryisnone. Checkwritablebefore a write and you never send one that cannot land. Full detail: https://repull.dev/docs/errors/listing_not_api_connected
Body by type
model—{"type": "model", "modelType": "STANDARD"}.modelTypeisSTANDARD,LOS_RECORDorRATE_PLAN.standard—{"type": "standard", "settings": {...}}. Standard pricing settings. The object replaces the current one, soGETthe pricing first, change it, andPUTthe whole object back.los—{"type": "los", "records": [{"check_in_date": "2026-09-15", "guest_count": 2, "los_data": [[1, 120], [7, 700]]}]}. A non-empty array; each record needscheck_in_date,guest_count(at least 1) andlos_dataas[nights, price]pairs.rate-plan—{"type": "rate-plan", "settings": {...}}. Rate-plan pricing settings; replaces the current object.fees— change the listing's fees. Airbnb replaces the whole fee list on every write: send{"type": "fees", "settings": {"standard_fees": [...]}}and any fee you leave out is deleted. Usefeesinstead and Repull keeps the rest for you:{"type": "fees", "fees": [{"fee_type": "PASS_THROUGH_MANAGEMENT_FEE", "amount": 10, "amount_type": "percent"}]}sets that one fee and keeps every other;"amount": nullremoves just that fee. The response is the listing's fees as Airbnb holds them afterwards. Sendfeesorsettings, not both.currency—{"type": "currency", "currency": "USD"}. An ISO 4217 code in capitals.rule—{"type": "rule", "rule": {...}}. Adds one pricing rule to the listing.calendar—{"type": "calendar", "operations": [...]}. Per-date price and restrictions; operation fields below.
Fees
The same units GET …/pricing returns, so a fee you read can be written back unchanged.
amount— for aflatfee, the amount in the listing currency × 1,000,000 (160000000= 160.00). For apercentfee, a whole percent of the rent (10= 10%). Percent is accepted for management and resort fees.nullremoves the fee.fee_type—PASS_THROUGH_CLEANING_FEE,PASS_THROUGH_SHORT_TERM_CLEANING_FEE,PASS_THROUGH_PET_FEE,PASS_THROUGH_SECURITY_DEPOSIT,PASS_THROUGH_MANAGEMENT_FEE,PASS_THROUGH_RESORT_FEE,PASS_THROUGH_COMMUNITY_FEE,PASS_THROUGH_LINEN_FEE. One fee per type.amount_type—flatorpercent.charge_type—PER_GROUP,PER_PERSONorPER_PET.charge_period—PER_BOOKINGorPER_NIGHT.offline—truewhen the host collects it outside Airbnb. Each defaults to the existing fee's value, elseflat/PER_GROUP/PER_BOOKING/false.- To update one fee without touching the others, send only that fee in
fees. To change several, send them together — one write, one read-back.
Calendar operations
- Dates — either
dates(a non-empty array ofYYYY-MM-DDdates or inclusive rangesYYYY-MM-DD:YYYY-MM-DD) orstart_date+end_date(inclusive, sent together,end_dateon or afterstart_date). Not both. daily_price— nightly price, a number ≥ 0 in the listing currency.availability—availablereopens the dates,unavailableblocks them (stop-sell),defaultfalls back to the listing rules.busy_subtype— why a blocked date is blocked:BLOCKED_BY_HOSTorOUTSIDE_RESERVATION. Airbnb requires it wheneveravailabilityisunavailable; if you leave it out,BLOCKED_BY_HOSTis sent. UseOUTSIDE_RESERVATIONfor dates held by a booking made on another channel.min_nights,max_nights— whole numbers from 1 to 1125 (Airbnb's limit);max_nightscannot be lower thanmin_nights.closed_to_arrival,closed_to_departure— JSON booleans (true/false, not strings).notes— free text.operationsmust contain at least one operation. Unknown fields are refused rather than ignored: sendingpricereturns422 invalid_paramsnamingoperations.0.price(the field isdaily_price), so a misspelling can never look like a successful write.
Errors
A successful write returns 200 with Airbnb's result.
422 invalid_params— the body failed validation before anything was sent to Airbnb.fieldnames the field (for exampleoperations.0.max_nights),value_receivedechoes it andfixsays what to send.422 airbnb_rejected— Airbnb refused the change.messagecarries Airbnb's own reason. Correct the request; sending the same body again is refused again.403 listing_not_api_connected— Airbnb API sync is off for this listing (its sync category isnone), so Airbnb accepts no writes to it and nothing was sent. Reconnecting the Airbnb account does not fix this — the host has to turn API sync on for that one listing inside Airbnb. See the section above, and https://repull.dev/docs/errors/listing_not_api_connected403 connection_reauth_required— the host's Airbnb authorization expired or was revoked, or Airbnb refused to refresh it. This takes the whole account down, not one listing. Retrying will not help. Reconnect Airbnb at https://repull.dev/dashboard/connections (orPOST /v1/connect/airbnb), then retry.403 listing_inactive— the listing is inactive. Activate it withPATCH /v1/listings/{id}and{"active": true}, then retry.404 not_found— no Airbnb-connected listing with this id in your workspace. Check the id is the Repull listing id.404 no_connection— the workspace has no Airbnb connection at all.429 airbnb_rate_limited— Airbnb is rate-limiting writes for this host. Waitretry_afterseconds when present, otherwise back off exponentially, and put many dates in oneoperationsarray instead of one call per date.502 airbnb_error— Airbnb had an outage or timed out. Nothing about the request needs to change: retry with backoff.
Example
# Add a 10% management fee and keep every other fee (4118 is the Repull listing id)
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/pricing \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "fees", "fees": [{"fee_type": "PASS_THROUGH_MANAGEMENT_FEE", "amount": 10, "amount_type": "percent"}]}'
# Set the cleaning fee to 160.00 and remove the pet fee
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/pricing \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "fees", "fees": [{"fee_type": "PASS_THROUGH_CLEANING_FEE", "amount": 160000000, "amount_type": "flat"}, {"fee_type": "PASS_THROUGH_PET_FEE", "amount": null}]}'
# Update the base nightly rate
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/pricing \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "standard", "settings": {"default_daily_price": 250}}'
# Set price and stay limits for specific dates
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/pricing \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "calendar",
"operations": [
{
"dates": ["2026-06-01", "2026-06-02"],
"availability": "available",
"daily_price": 300,
"min_nights": 2,
"max_nights": 14,
"closed_to_arrival": false,
"closed_to_departure": false
}
]
}'
# Block a range held by a booking made on another channel
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/pricing \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "calendar", "operations": [{"dates": ["2026-07-01:2026-07-04"], "availability": "unavailable", "busy_subtype": "OUTSIDE_RESERVATION"}]}'Response
// 422 — a field failed validation; nothing was sent to Airbnb
{
"error": {
"code": "invalid_params",
"message": "`operations.0.max_nights` is invalid: Number must be less than or equal to 1125",
"fix": "Send a whole number of nights between 1 and 1125, no lower than `min_nights`.",
"field": "operations.0.max_nights",
"value_received": "2000",
"docs_url": "https://repull.dev/docs/errors/invalid_params",
"request_id": "req_01J5X7Y8Z9ABCDEF12345678"
}
}