REST API reference

Meevo API

14 endpoints for Meevo. Each one is a POST with a JSON body, called with your API key.

Base URL
https://cotlet.dev/api/v1/meevo
Connects with
Your Meevo staff login, with security access to the areas you use
Integration page
Meevo
Meevo Endpoints
Endpoint Access Description
list_locations read Locations your login can reach, with address and time zone.
list_services read Service menu of a location by category, with duration, price and add-ons.
list_staff read Employees of a location with title and the services each one performs.
list_appointments read Appointments in the Appointment Book for a date range, with client, services, employee and confirmation status.
find_open_slots read Open times for a service in a date range, with the employees who can perform it.
find_client read Search clients by name, email or phone; returns contact details and client type.
get_client read Client profile with upcoming appointments, visit notes, memberships, packages, gift cards and points.
list_packages read Package and membership definitions of a location with price and included services.
get_register_summary read The end-of-day Register Summary: sales by type, payment methods, membership sales, returns and deposits.
add_visit_note write Add an internal visit note to a client profile.
book_appointment write Book one or more services for a client with an employee; Meevo sends your usual confirmation.
reschedule_appointment write Move an appointment to a new time or employee.
cancel_appointment write Cancel an appointment with one of your cancellation reasons.
sell_package write Ring up a package for a client in the Register and record the payment.

POST https://cotlet.dev/api/v1/meevo/list_locations

Returns every Meevo location your staff login can reach. Use location_id from each item as the location_id parameter of the other tools. Time zone is the one set on the location.

Parameters

No parameters.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/list_locations \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("meevo", "list_locations")
Node.js
const result = await cotlet.call('meevo', 'list_locations');
CLI
cotlet call meevo list_locations

Example response

{
  "locations": [
    {
      "location_id": "201",
      "name": "Maple Street Salon",
      "address": "12 Maple St, Hoboken, NJ",
      "time_zone": "America/New_York"
    },
    {
      "location_id": "202",
      "name": "Harbor Spa",
      "address": "88 Harbor Rd, Jersey City, NJ",
      "time_zone": "America/New_York"
    }
  ]
}

POST https://cotlet.dev/api/v1/meevo/list_services

Lists the service menu of one location grouped by category. Each service has its duration, price and add-ons. Use service_id with find_open_slots and book_appointment.

Parameters

Parameters: list_services
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.
category string Only this service category.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/list_services \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("meevo", "list_services")
Node.js
const result = await cotlet.call('meevo', 'list_services');
CLI
cotlet call meevo list_services

Example response

{
  "categories": [
    {
      "category": "Color",
      "services": [
        {
          "service_id": "9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
          "name": "Balayage",
          "duration_minutes": 150,
          "price": 220,
          "add_ons": [
            "Toner"
          ]
        }
      ]
    }
  ]
}

List staff

read

POST https://cotlet.dev/api/v1/meevo/list_staff

Lists the employees of one location with their title and the services each performs. Use staff_id to narrow list_appointments and find_open_slots, or to book with a specific employee.

Parameters

Parameters: list_staff
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/list_staff \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("meevo", "list_staff")
Node.js
const result = await cotlet.call('meevo', 'list_staff');
CLI
cotlet call meevo list_staff

Example response

{
  "staff": [
    {
      "staff_id": "e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b",
      "name": "Alex Rivera",
      "title": "Senior Stylist",
      "services": [
        "Balayage",
        "Haircut"
      ]
    },
    {
      "staff_id": "a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d",
      "name": "Sam Patel",
      "title": "Stylist",
      "services": [
        "Balayage",
        "Blowout"
      ]
    }
  ]
}

POST https://cotlet.dev/api/v1/meevo/list_appointments

Returns appointments from the Appointment Book for one location, oldest start first. Canceled appointments are left out unless include_canceled is true. Confirmation status is the one Meevo shows on the appointment. Use appointment_id with reschedule_appointment and cancel_appointment.

Parameters

Parameters: list_appointments
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.
from required date First day, inclusive.
to date Last day, inclusive. Default: same as from.
staff_id string Only this employee.
include_canceled boolean Also return canceled appointments. Default: false.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/list_appointments \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"2026-10-01"}'
Python
result = client.call("meevo", "list_appointments", {"from":"2026-10-01"})
Node.js
const result = await cotlet.call('meevo', 'list_appointments', {"from":"2026-10-01"});
CLI
cotlet call meevo list_appointments --data '{"from":"2026-10-01"}'

Example response

{
  "appointments": [
    {
      "appointment_id": "4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9",
      "start": "2026-10-12T09:00:00-04:00",
      "end": "2026-10-12T11:30:00-04:00",
      "client": {
        "id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
        "name": "Jamie Doe"
      },
      "services": [
        "Balayage"
      ],
      "staff": "Alex Rivera",
      "confirmation_status": "confirmed"
    },
    {
      "appointment_id": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
      "start": "2026-10-12T14:00:00-04:00",
      "end": "2026-10-12T14:45:00-04:00",
      "client": {
        "id": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a",
        "name": "Sam Lee"
      },
      "services": [
        "Haircut"
      ],
      "staff": "Alex Rivera",
      "confirmation_status": "unconfirmed"
    }
  ]
}

POST https://cotlet.dev/api/v1/meevo/find_open_slots

Returns open start times for one service in a date range, earliest first, each with the employees free at that time. Without staff_id it searches every employee who performs the service. Use a start and staff_id from the result with book_appointment.

Parameters

Parameters: find_open_slots
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.
service_id required string Service ID from list_services.
from required date First day to search.
to required date Last day to search.
staff_id string Only this employee. Default: anyone who performs the service.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/find_open_slots \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"location_id":"201","service_id":"9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d","from":"2026-10-18","to":"2026-10-19"}'
Python
result = client.call("meevo", "find_open_slots", {"location_id":"201","service_id":"9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d","from":"2026-10-18","to":"2026-10-19"})
Node.js
const result = await cotlet.call('meevo', 'find_open_slots', {"location_id":"201","service_id":"9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d","from":"2026-10-18","to":"2026-10-19"});
CLI
cotlet call meevo find_open_slots --data '{"location_id":"201","service_id":"9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d","from":"2026-10-18","to":"2026-10-19"}'

Example response

{
  "slots": [
    {
      "start": "2026-10-17T10:00:00-04:00",
      "staff": [
        {
          "staff_id": "e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b",
          "name": "Alex Rivera"
        }
      ]
    },
    {
      "start": "2026-10-17T11:30:00-04:00",
      "staff": [
        {
          "staff_id": "a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d",
          "name": "Sam Patel"
        }
      ]
    }
  ]
}

POST https://cotlet.dev/api/v1/meevo/find_client

Searches client profiles by name, email or phone and returns the matches with contact details and client type. Use client_id with get_client, book_appointment and sell_package. If several clients match, your agent should ask which one before it books.

Parameters

Parameters: find_client
NameTypeDescription
query required string Name, email or phone number.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/find_client \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"query"}'
Python
result = client.call("meevo", "find_client", {"query":"query"})
Node.js
const result = await cotlet.call('meevo', 'find_client', {"query":"query"});
CLI
cotlet call meevo find_client --data '{"query":"query"}'

Example response

{
  "clients": [
    {
      "client_id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
      "name": "Jamie Doe",
      "email": "client@example.com",
      "phone": "+15555550123",
      "client_type": "Regular"
    }
  ]
}

Get client

read

POST https://cotlet.dev/api/v1/meevo/get_client

Returns one client profile with upcoming appointments, visit notes, memberships, packages, gift cards and points. Use it before booking or selling, so your agent sees what the client already owns.

Parameters

Parameters: get_client
NameTypeDescription
client_id required string Client ID from find_client.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/get_client \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2"}'
Python
result = client.call("meevo", "get_client", {"client_id":"client_8c41d2"})
Node.js
const result = await cotlet.call('meevo', 'get_client', {"client_id":"client_8c41d2"});
CLI
cotlet call meevo get_client --data '{"client_id":"client_8c41d2"}'

Example response

{
  "client_id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
  "name": "Jamie Doe",
  "upcoming_appointments": [
    {
      "appointment_id": "4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9",
      "start": "2026-10-12T09:00:00-04:00",
      "services": [
        "Balayage"
      ]
    }
  ],
  "visit_notes": [
    {
      "note_type": "Color formula",
      "text": "Formula 7N plus 20 vol.",
      "created_at": "2026-09-14T16:20:00-04:00"
    }
  ],
  "packages": [
    {
      "name": "5 Blowouts",
      "visits_left": 2
    }
  ],
  "memberships": [],
  "gift_cards": [],
  "points": 120
}

POST https://cotlet.dev/api/v1/meevo/list_packages

Lists the packages and memberships you sell at one location, with price and included services. kind narrows the list. Use package_id with sell_package.

Parameters

Parameters: list_packages
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.
kind enum packages, memberships or all. Default: all.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/list_packages \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("meevo", "list_packages")
Node.js
const result = await cotlet.call('meevo', 'list_packages');
CLI
cotlet call meevo list_packages

Example response

{
  "packages": [
    {
      "package_id": "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
      "kind": "package",
      "name": "5 Blowouts",
      "price": 200,
      "includes": [
        "Blowout x5"
      ]
    }
  ]
}

POST https://cotlet.dev/api/v1/meevo/get_register_summary

Returns the Register Summary of one location for one business day: sales by type, payments by method, membership sales, returns and deposits. Sales by type add up to total_sales, and payments add up to the same total. Reads one location per call.

Parameters

Parameters: get_register_summary
NameTypeDescription
location_id string Location ID from list_locations. Default: the location you signed in to.
date required date Business day to read.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/get_register_summary \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"location_id":"201","date":"2026-10-10"}'
Python
result = client.call("meevo", "get_register_summary", {"location_id":"201","date":"2026-10-10"})
Node.js
const result = await cotlet.call('meevo', 'get_register_summary', {"location_id":"201","date":"2026-10-10"});
CLI
cotlet call meevo get_register_summary --data '{"location_id":"201","date":"2026-10-10"}'

Example response

{
  "location_id": "201",
  "date": "2026-10-10",
  "currency": "USD",
  "sales_by_type": {
    "services": 2840,
    "products": 410,
    "packages": 600
  },
  "total_sales": 3850,
  "payments": {
    "card": 3120.5,
    "cash": 500,
    "gift_card": 229.5
  },
  "membership_sales": 0,
  "returns": 0,
  "deposits": 150
}

Add visit note

write Confirm

POST https://cotlet.dev/api/v1/meevo/add_visit_note

Adds an internal visit note to a client profile, for example a color formula. The note is visible to staff, not to the client. note_type must be one set up at your location. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: add_visit_note
NameTypeDescription
client_id required string Client ID from find_client.
text required string Note text.
note_type string Visit note type as set up at your location.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/add_visit_note \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","text":"text"}'
Python
result = client.call("meevo", "add_visit_note", {"client_id":"client_8c41d2","text":"text"})
Node.js
const result = await cotlet.call('meevo', 'add_visit_note', {"client_id":"client_8c41d2","text":"text"});
CLI
cotlet call meevo add_visit_note --data '{"client_id":"client_8c41d2","text":"text"}'

Example response

{
  "note_id": "n_20311",
  "client_id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
  "note_type": "Color formula",
  "status": "saved"
}

Book appointment

write Confirm

POST https://cotlet.dev/api/v1/meevo/book_appointment

Books one or more services in order for a client with one employee, starting at the time you give. Meevo sends your usual confirmation to the client. The call fails if the time is no longer free. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: book_appointment
NameTypeDescription
client_id required string Client ID from find_client.
location_id string Location ID from list_locations. Default: the location you signed in to.
service_ids required string[] Service IDs from list_services, in order.
staff_id required string Employee performing the services.
start required datetime ISO 8601 with time zone.
note string Appointment note.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/book_appointment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60","location_id":"201","service_ids":["9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"],"staff_id":"e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b","start":"2026-10-17T10:00:00-04:00"}'
Python
result = client.call("meevo", "book_appointment", {"client_id":"c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60","location_id":"201","service_ids":["9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"],"staff_id":"e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b","start":"2026-10-17T10:00:00-04:00"})
Node.js
const result = await cotlet.call('meevo', 'book_appointment', {"client_id":"c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60","location_id":"201","service_ids":["9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"],"staff_id":"e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b","start":"2026-10-17T10:00:00-04:00"});
CLI
cotlet call meevo book_appointment --data '{"client_id":"c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60","location_id":"201","service_ids":["9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d"],"staff_id":"e1d2c3b4-a5f6-4e7d-9c8b-7a6f5e4d3c2b","start":"2026-10-17T10:00:00-04:00"}'

Example response

{
  "appointment_id": "4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9",
  "status": "booked",
  "client": {
    "id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
    "name": "Jamie Doe",
    "email": "client@example.com"
  },
  "services": [
    {
      "id": "9a8b7c6d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
      "name": "Balayage",
      "duration_minutes": 150,
      "staff": "Alex Rivera"
    }
  ],
  "start": "2026-10-17T10:00:00-04:00",
  "end": "2026-10-17T12:30:00-04:00",
  "confirmation_status": "unconfirmed"
}

Reschedule appointment

write Confirm

POST https://cotlet.dev/api/v1/meevo/reschedule_appointment

Moves one appointment to a new start time, a new employee, or both. The services stay the same. Meevo sends your usual confirmation for the changed appointment. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: reschedule_appointment
NameTypeDescription
appointment_id required string Appointment ID from list_appointments.
start required datetime New start, ISO 8601 with time zone.
staff_id string New employee. Default: unchanged.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/reschedule_appointment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"appointment_id":"4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9","start":"2026-10-16T09:00:00-04:00","staff_id":"a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d"}'
Python
result = client.call("meevo", "reschedule_appointment", {"appointment_id":"4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9","start":"2026-10-16T09:00:00-04:00","staff_id":"a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d"})
Node.js
const result = await cotlet.call('meevo', 'reschedule_appointment', {"appointment_id":"4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9","start":"2026-10-16T09:00:00-04:00","staff_id":"a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d"});
CLI
cotlet call meevo reschedule_appointment --data '{"appointment_id":"4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9","start":"2026-10-16T09:00:00-04:00","staff_id":"a7b8c9d0-e1f2-4a3b-8c4d-9e0f1a2b3c4d"}'

Example response

{
  "appointment_id": "4b5c6d7e-8f90-4a1b-b2c3-d4e5f6a7b8c9",
  "status": "rescheduled",
  "start": "2026-10-17T10:00:00-04:00",
  "end": "2026-10-17T12:30:00-04:00",
  "staff": "Sam Patel"
}

Cancel appointment

write Confirm

POST https://cotlet.dev/api/v1/meevo/cancel_appointment

Cancels one appointment and records the reason you give. reason must be one set up at your location. Canceling affects the client's booking, so confirm it. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: cancel_appointment
NameTypeDescription
appointment_id required string Appointment ID from list_appointments.
reason required string Cancellation reason as set up at your location.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/cancel_appointment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"appointment_id":"appointment_8c41d2","reason":"reason"}'
Python
result = client.call("meevo", "cancel_appointment", {"appointment_id":"appointment_8c41d2","reason":"reason"})
Node.js
const result = await cotlet.call('meevo', 'cancel_appointment', {"appointment_id":"appointment_8c41d2","reason":"reason"});
CLI
cotlet call meevo cancel_appointment --data '{"appointment_id":"appointment_8c41d2","reason":"reason"}'

Example response

{
  "appointment_id": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
  "status": "canceled",
  "reason": "Client request"
}

Sell package

write Confirm

POST https://cotlet.dev/api/v1/meevo/sell_package

Rings up one package for a client in the Register and records the payment. payment_type must match a payment type named in your Register. It moves money, so confirm it. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: sell_package
NameTypeDescription
client_id required string Client ID from find_client.
location_id string Location ID from list_locations. Default: the location you signed in to.
package_id required string Package ID from list_packages.
payment_type required string Payment type as named in your Register, e.g. Cash or Visa.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/meevo/sell_package \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","package_id":"package_8c41d2","payment_type":"payment type"}'
Python
result = client.call("meevo", "sell_package", {"client_id":"client_8c41d2","package_id":"package_8c41d2","payment_type":"payment type"})
Node.js
const result = await cotlet.call('meevo', 'sell_package', {"client_id":"client_8c41d2","package_id":"package_8c41d2","payment_type":"payment type"});
CLI
cotlet call meevo sell_package --data '{"client_id":"client_8c41d2","package_id":"package_8c41d2","payment_type":"payment type"}'

Example response

{
  "sale_id": "s_88421",
  "status": "paid",
  "client_id": "c3f1a2b4-5d6e-4f70-8a91-0b2c3d4e5f60",
  "package": "5 Blowouts",
  "amount": 200,
  "payment_type": "Cash"
}