Embeddable Widgets
Add booking, reviews, portfolios, and profile cards to any website with a simple iframe embed. Fully customizable accent colors, automatic resizing, and WCAG-accessible.
Quick Start
Get a widget running on your site in under 2 minutes.
- Get an API key — Go to Settings → API & Integrations and create a new API key.
- Copy your stylist/salon ID— Find it in the URL of your public profile (e.g.
/stylists/abc-123). - Paste this snippetinto your website's HTML:
<iframe
src="https://ratemystylist.com/embed/badge/YOUR_STYLIST_ID?key=rms_YOUR_KEY"
style="width:100%;border:none;overflow:hidden"
loading="lazy"
></iframe>
<script>
window.addEventListener("message", function(e) {
if (e.data?.type === "rms-resize") {
document.querySelectorAll('iframe[src*="/embed/"]').forEach(function(f) {
if (e.source === f.contentWindow) f.style.height = e.data.height + "px";
});
}
});
</script>The resize script is optional but recommended — it automatically adjusts the iframe height to fit the widget content.
Available Widgets
Badge
Free/embed/badge/:idCompact inline card with avatar, name, star rating, and review count. Perfect for sidebars and footers.
Profile Card
Free/embed/profile/:idFull profile card with avatar, headline, specialties, location, rating, and a CTA button linking to the full profile.
Reviews Carousel
Pro/embed/reviews/:idHorizontally scrollable carousel of the 10 most recent reviews with client info, star ratings, and excerpts.
Portfolio Gallery
Pro/embed/portfolio/:idResponsive grid of portfolio images with lazy loading, hover captions, and tap support on touch devices.
Booking (Stylist)
Pro/embed/booking/:idFull multi-step booking flow: service selection, date picker, time slots, contact form, and confirmation.
Booking (Salon)
Business/embed/booking/salon/:idSalon-level booking with stylist selection (pick, next-available, or both), service menu, and scheduling.
The :id parameter is the stylist profile ID (UUID) for stylist widgets, or the salon ID for salon widgets.
Authentication
Every widget request requires a valid API key. Keys are passed via the key query parameter or the Authorization header.
Query Parameter (recommended for iframes)
/embed/badge/STYLIST_ID?key=rms_YOUR_API_KEYAuthorization Header (for API calls)
Authorization: Bearer rms_YOUR_API_KEYAPI key visibility
API keys embedded in iframe URLs are visible in the page source. Use domain allowlisting to restrict which domains can use your key. This prevents unauthorized usage even if the key is exposed.
Customization
Accent Color
Override the default pink accent color by adding the accent query parameter with a hex color code (3 or 6 digits, no # needed):
<!-- Indigo accent -->
<iframe src="/embed/booking/ID?key=rms_KEY&accent=4f46e5" ...></iframe>
<!-- Teal accent -->
<iframe src="/embed/badge/ID?key=rms_KEY&accent=0d9488" ...></iframe>
<!-- Short hex (3 digits) -->
<iframe src="/embed/profile/ID?key=rms_KEY&accent=e60" ...></iframe>The accent color automatically derives hover, light background, and text variants. No additional configuration needed.
CSS Variables
The following CSS custom properties are set on the widget body and drive all brand colors:
| Variable | Default | Usage |
|---|---|---|
| --accent | #db2777 | Primary buttons, active states, focus rings |
| --accent-hover | #be185d | Button hover states |
| --accent-light | #fdf2f8 | Selected item backgrounds, badge backgrounds |
| --accent-text | #be185d | Text on light accent backgrounds |
Accessibility
All widgets include built-in accessibility features:
- WCAG-compliant visible form labels and required field indicators
- Focus-visible ring outlines on all interactive elements
- Minimum 12px font size throughout (WCAG AA)
- SVG star rating icons (not text characters)
prefers-reduced-motionsupport — animations are suppressed automatically- Semantic HTML with proper ARIA attributes
Auto-Resize
Widgets emit a postMessage whenever their content height changes. Add this listener to your page to auto-resize the iframe:
window.addEventListener("message", function(event) {
if (event.data?.type === "rms-resize") {
// Find the iframe that sent the message
document.querySelectorAll('iframe[src*="/embed/"]').forEach(function(frame) {
if (event.source === frame.contentWindow) {
frame.style.height = event.data.height + "px";
}
});
}
});Message Format
| Field | Type | Description |
|---|---|---|
| type | string | Always "rms-resize" |
| height | number | Content height in pixels |
Height updates fire on initial load and whenever the DOM changes (e.g. booking step transitions, loading states).
API Reference
In addition to iframe widgets, you can call the REST API directly to build custom integrations. All endpoints require an API key via the Authorization: Bearer header.
Stylist Endpoints
/api/v1/stylist/:id/profileStylist bio, headline, specialties, rating, verification status
/api/v1/stylist/:id/reviewsPaginated reviews with client info and ratings
?page=1&limit=10&sort=recent/api/v1/stylist/:id/servicesActive services with add-ons, pricing, and duration
/api/v1/stylist/:id/portfolioPaginated portfolio items with collection filter
?page=1&limit=12&collection=ID/api/v1/stylist/:id/availabilityAvailable time slots for a given date and service
?date=2026-04-10&serviceId=ID/api/v1/stylist/:id/bookingsPro+Create a booking request
Salon Endpoints
/api/v1/salon/:id/servicesAll services grouped by stylist
/api/v1/salon/:id/availabilitySlots with stylist info
?date=2026-04-10&serviceId=ID&stylistId=ID/api/v1/salon/:id/bookingsBusiness+Create a salon booking with optional stylist preference
Booking POST Body
{
"serviceId": "service-uuid",
"date": "2026-04-10",
"startTime": "2026-04-10T14:00:00.000Z",
"guest": {
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "+15551234567"
},
"notes": "First visit, prefer low-maintenance style"
}Query Parameters
keystringrequiredAPI key (alternative to Authorization header). Prefix: rms_
pagenumberPage number for paginated endpoints. Default: 1
limitnumberItems per page. Default: 10, max: 50
sortstringSort order for reviews: recent or highest
datestringISO date (YYYY-MM-DD) for availability queries
serviceIdstringService UUID for availability queries
Error Responses
| Status | Meaning |
|---|---|
| 401 | Invalid, revoked, or missing API key |
| 403 | Domain not in allowlist, or insufficient tier |
| 404 | Stylist or salon not found |
| 409 | Time slot no longer available (double-booking prevented) |
| 429 | Monthly rate limit exceeded |
Rate Limits
API calls are metered monthly per key. The counter resets on the 1st of each month. When you exceed your limit, all requests return 429 Too Many Requests until the next period.
| Tier | Monthly Limit | Typical Use |
|---|---|---|
| Free | 1,000 | Personal site, testing |
| Pro | 50,000 | Business website with booking |
| Business | 200,000 | Multi-location salon |
Check your current usage in Settings → API & Integrations. Each API key shows its call count for the current period.
Domain Allowlist
Restrict which domains can use your API key. When configured, requests without a matching Origin or Referer header are rejected with 403.
["example.com", "staging.example.com", "localhost"]- Domain matching is exact (no wildcards)
- If the allowlist is empty, all origins are accepted
- Free tier: 1 domain, Pro: 5 domains, Business: unlimited
- Manage domains in Settings or via the API keys PUT endpoint
Tip: Always add localhost during development, and remove it before going to production.
Subscription Tiers
| Feature | Free | Pro | Business |
|---|---|---|---|
| API calls / month | 1,000 | 50,000 | 200,000 |
| Allowed domains | 1 | 5 | Unlimited |
| Badge widget | Yes | Yes | Yes |
| Profile card widget | Yes | Yes | Yes |
| Reviews carousel | No | Yes | Yes |
| Portfolio gallery | No | Yes | Yes |
| Booking widget | No | Yes | Yes |
| Salon booking widget | No | No | Yes |
| "Powered by" branding | Shown | Hidden | Hidden |
| API keys per account | 5 | 5 | 5 |
Upgrade your tier in Settings → Subscription Tiers.
Need help? Reach out at support@ratemystylist.com