Skip to content
Agency plan

The Husly API

Manage sites, pages, blog posts and media from your own script, from Zapier, or from your agency tooling. A versioned REST interface, authenticated with an API key.

Create an API key
What you need

The API is part of the Agency plan. The account owner creates a key under My account -> API keys. The full key is shown exactly ONCE, so store it right away.

Get started

curl
# Who am I? Returns the account id and the key's scopes.
curl https://api.husly.app/api/v1/me \
  -H "Authorization: Bearer hsly_live_ab12cd34ef56_..."

# List the sites on this account.
curl https://api.husly.app/api/v1/sites \
  -H "Authorization: Bearer hsly_live_ab12cd34ef56_..."

Authentication

Every request carries the API key. Both forms below work the same way - use whichever your tool supports. A key always starts with the prefix hsly_live_. A request with no key, or with a revoked one, gets a 401.

HTTP
Authorization: Bearer hsly_live_ab12cd34ef56_XXXXXXXXXXXXXXXXXXXXXXXX

# or

X-Api-Key: hsly_live_ab12cd34ef56_XXXXXXXXXXXXXXXXXXXXXXXX
The key is a secret

Never put a key in browser-side code or in a public repository - it reaches the whole account. Keep it in a server-side environment variable. A leaked key can be revoked immediately and replaced.

Scopes

A key carries exactly the scopes you ticked when you created it. A missing scope answers 403 insufficient_scope. Give each key only what it truly needs: a Zapier key that reads form replies has no business deleting sites.

Endpoints

Every path is relative to https://api.husly.app. :siteId is the site id from the GET /api/v1/sites response. The site must belong to your account - a stranger's site id answers 404, not 403, because a key must not learn that other accounts exist.

Account

Sites

Pages

Blog

Media

Forms

Redirects

Menus

Analytics

Webhooks

Example: publish a blog post

A post's body is a block tree - the same shape the builder saves. The simplest start is a single richtext block. Leave layoutJson out and you get an empty post you can finish in the builder.

curl
curl -X POST https://api.husly.app/api/v1/sites/SITE_ID/posts \
  -H "Authorization: Bearer hsly_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "kevadised-pakkumised",
    "title":   { "et": "Kevadised pakkumised", "en": "Spring offers" },
    "excerpt": { "et": "Lühike sissejuhatus.", "en": "A short intro." },
    "status": "published",
    "authorName": "Mari Maasikas",
    "layoutJson": {
      "contentWidth": "narrow",
      "blocks": [
        { "id": "b1", "type": "richtext", "props": {
            "content": { "et": "<p>Tere tulemast!</p>", "en": "<p>Welcome!</p>" } } }
      ]
    }
  }'

Errors

An error is always JSON shaped { "error": "code" }, sometimes with extra fields (required, limit and so on). The code is machine-readable and stable - branch on the code, never on the message.

Limits

Requests are capped per key per minute. Going over answers 429 with a Retry-After header, and the body's `limit` field says which cap applied. Plan quotas - number of sites, number of pages, storage - apply through the API as well: a script cannot walk around them.

Versioning

The current version is v1. We will not reshape a v1 response in a way that breaks your integration - new fields may appear, existing ones will not vanish. A breaking change would mean a new path (/api/v2/).

The Rentals partner API

A separate API for travel agencies, channel managers and AI agents that sell one Husly rental business's cars, bikes, boats, gear or places to stay. The site owner makes the key on the Rentals "Integrations" tab (Partner API) and gives it to the partner. A key opens that one site only: its published catalogue and the bookings the partner made. No Agency plan is needed: it comes with the Rentals add-on.

A different key, a different address

A partner key starts with hsly_partner_ and works only under /api/partner/v1/rentals. An account API key (hsly_live_) does not work here, and a partner key does not work in the account API.

curl
# The site, its terms, and what this key may do.
curl https://api.husly.app/api/partner/v1/rentals/me \
  -H "Authorization: Bearer hsly_partner_ab12cd34ef56_..."

# What is free from 12 to 14 June, with the lowest price.
curl "https://api.husly.app/api/partner/v1/rentals/listings?from=2027-06-12&to=2027-06-14" \
  -H "Authorization: Bearer hsly_partner_ab12cd34ef56_..."

# Hold a car for 20 minutes...
curl -X POST https://api.husly.app/api/partner/v1/rentals/bookings \
  -H "Authorization: Bearer hsly_partner_ab12cd34ef56_..." \
  -H "Content-Type: application/json" \
  -d '{
    "listing": "toyota-rav4",
    "from": "2027-06-12",
    "to": "2027-06-14",
    "guest": { "name": "Mari Maasikas", "email": "[email protected]", "phone": "+372 5555 5555" },
    "termsAccepted": true,
    "hold": true,
    "reference": "AG-10442"
  }'

# ...and book it once the traveller says yes.
curl -X POST https://api.husly.app/api/partner/v1/rentals/bookings/BOOKING_ID/confirm \
  -H "Authorization: Bearer hsly_partner_ab12cd34ef56_..."

Partner API endpoints

Hold first, then confirm

"hold": true keeps the dates for 20 minutes (at most 60) and writes to nobody. POST /bookings/:id/confirm books them; a hold that is not confirmed lets the dates go by itself. Sending the same "reference" again returns the same booking, not a second one. The price and the free days are the same as on the rental business's own site. A partner's booking is not paid on Husly: the partner settles the money with the renter.

AI agents (MCP)

The same API is also an MCP server at POST /api/partner/v1/rentals/mcp, with the same key. It speaks MCP 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26. Tools: rentals_site_info, search_rentals, get_rental, get_rental_calendar, quote_rental, book_rental, confirm_booking, cancel_booking, get_booking, list_bookings. A read-only key gets no booking tools. book_rental holds the dates by default and tells the agent to get the traveller's yes before confirm_booking.

mcp.json
{
  "mcpServers": {
    "husly-rentals": {
      "type": "http",
      "url": "https://api.husly.app/api/partner/v1/rentals/mcp",
      "headers": {
        "Authorization": "Bearer hsly_partner_ab12cd34ef56_..."
      }
    }
  }
}

The partner's webhook

The partner sets its own address with PUT /api/partner/v1/rentals/webhook; the signing secret is shown once. Events: rental.booking.created, rental.booking.confirmed, rental.booking.cancelled, for the partner's own bookings only. The signature is the same as the account webhooks': X-Husly-Signature: sha256=<hex>, the HMAC-SHA256 of <timestamp>.<body>.

The full reference

Every field and every answer's shape is in the partner API's own reference and its OpenAPI 3.1 file, which you can load into Postman or generate a client from.

Frequently asked questions

Ready to start?

The API is part of the Agency plan. If you already have an account, a key is a few clicks away.

Create an API key