REST API reference

Perfect Venue API

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

Base URL
https://cotlet.dev/api/v1/perfect-venue
Connects with
Your own Perfect Venue account (Admin or Editor to change events; Viewer and Limited View are read only)
Integration page
Perfect Venue
Perfect Venue Endpoints
Endpoint Access Description
list_events read Events and leads with status, dates, guest count, contact and event owner.
get_event read One event with dates, spaces, guests, contact, status, notes, proposal totals and whether the proposal is locked.
list_payments read Payments of one event: deposits, scheduled payments and offline payments, with amount, method and date.
list_messages read The inbox thread of one event: emails to and from the contact with time and text.
list_email_templates read Your template emails from Settings, Email, with name, subject and text.
list_spaces read The spaces of your venue with their IDs.
get_events_report read One line per event, like Reports, Events: status, owner, dates and the sales breakdown.
create_lead write New inquiry in the Lead status with its contact. Nothing is sent to the guest.
update_event write Change date, time, guests, spaces, event type, owner or internal notes of an event.
set_event_status write Move an event to another status, with a lost reason when it is lost.
send_proposal write Send the event proposal to the guest, where they review it, sign and pay the deposit.
send_email write Email the event contact from the Perfect Venue inbox, from your text or a template.
log_offline_payment write Record a cash, check or in-house card payment on an event.
refund_payment write Refund an online payment in full or in part, with a reason.

POST https://cotlet.dev/api/v1/perfect-venue/list_events

Lists events from your account, including leads. Filter by status (lead, qualified, proposal_sent, confirmed, balance_due, completed or lost), by event date, by venue and by event owner. Each item has the event ID that the other tools take. Lost events are returned only when status is lost, as they are hidden from the home stages in the app.

Parameters

Parameters: list_events
NameTypeDescription
status enum lead, qualified, proposal_sent, confirmed, balance_due, completed or lost. Omit for all except lost.
from date Only events on or after this date.
to date Only events on or before this date.
venue_id string Limit to one venue when you manage several locations.
owner string Event owner, a team member email.
limit integer Events per page.
cursor string Next page cursor from the previous call.

Request

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

Example response

{
  "events": [
    {
      "event_id": "ev_8812",
      "name": "Smith rehearsal dinner",
      "status": "confirmed",
      "start_date": "2026-11-14",
      "start_time": "18:00",
      "end_time": "22:00",
      "group_size": 40,
      "spaces": [
        "Private Room"
      ],
      "owner": "maria@example.com",
      "contact": {
        "name": "Jane Smith",
        "email": "jane@example.com"
      }
    }
  ],
  "next_cursor": null
}

Get event

read

POST https://cotlet.dev/api/v1/perfect-venue/get_event

Returns the details of one event: date and time, spaces, group size, event type, owner, contact, status, internal notes and the proposal summary with totals, the deposit and the remaining balance. Use it before update_event or send_proposal. The proposal locks when your proposal locking rule says so (at signing, 2 weeks or 1 week before the event, or never), and the response tells you if it has.

Parameters

Parameters: get_event
NameTypeDescription
event_id required string Event ID from list_events.

Request

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

Example response

{
  "event_id": "ev_8812",
  "name": "Smith rehearsal dinner",
  "status": "confirmed",
  "event_type": "Rehearsal",
  "start_date": "2026-11-14",
  "start_time": "18:00",
  "end_time": "22:00",
  "group_size": 40,
  "spaces": [
    "Private Room"
  ],
  "owner": "maria@example.com",
  "contact": {
    "name": "Jane Smith",
    "email": "jane@example.com",
    "phone": "555-555-0101"
  },
  "internal_notes": "Vegetarian menu for 6 guests.",
  "proposal": {
    "total": 4800,
    "deposit": 1000,
    "paid": 1800,
    "balance_due": 3000,
    "locked": false
  }
}

POST https://cotlet.dev/api/v1/perfect-venue/list_payments

Returns the rows of the Payments tab of one event. Each payment says whether it was made online or logged offline, and its status. Offline payments already deduct from the total due on the proposal. Online payments can be refunded with refund_payment; offline payments cannot.

Parameters

Parameters: list_payments
NameTypeDescription
event_id required string Event ID from list_events.

Request

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

Example response

{
  "event_id": "ev_8812",
  "payments": [
    {
      "payment_id": "pay_3301",
      "type": "online",
      "purpose": "deposit",
      "amount": 1000,
      "method": "card",
      "status": "paid",
      "paid_on": "2026-10-04"
    },
    {
      "payment_id": "pay_3302",
      "type": "offline",
      "purpose": "remaining_balance",
      "amount": 800,
      "method": "check",
      "status": "paid",
      "paid_on": "2026-10-09"
    }
  ],
  "total": 4800,
  "balance_due": 3000
}

POST https://cotlet.dev/api/v1/perfect-venue/list_messages

Returns the emails of one event from the Perfect Venue inbox, so your agent sees who wrote last and when before it answers. Each message says whether it came from the guest or from your team.

Parameters

Parameters: list_messages
NameTypeDescription
event_id required string Event ID from list_events.

Request

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

Example response

{
  "event_id": "ev_8812",
  "messages": [
    {
      "from": "team",
      "sent_at": "2026-10-02T10:15:00Z",
      "subject": "Your event inquiry",
      "body": "Thanks for your inquiry. Here is our proposal."
    },
    {
      "from": "guest",
      "sent_at": "2026-10-03T08:40:00Z",
      "subject": "Re: Your event inquiry",
      "body": "Can we move to 60 guests?"
    }
  ]
}

POST https://cotlet.dev/api/v1/perfect-venue/list_email_templates

Returns the template emails you set up in Settings, Email. Use a template_id from this list in send_email. Templates carry the Personalize fields, which Perfect Venue fills in with the details of each event.

Parameters

No parameters.

Request

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

Example response

{
  "templates": [
    {
      "template_id": "tpl_followup",
      "name": "Follow-up",
      "subject": "Still looking at your date?",
      "body": "Hi, just checking in on your event."
    },
    {
      "template_id": "tpl_balance",
      "name": "Balance reminder",
      "subject": "Your remaining balance",
      "body": "Your remaining balance is due before your event."
    }
  ]
}

POST https://cotlet.dev/api/v1/perfect-venue/list_spaces

Returns the spaces you set up in Settings, Spaces, with the ID that update_event and create_lead take. Use it to name the room a guest asked for.

Parameters

Parameters: list_spaces
NameTypeDescription
venue_id string Limit to one venue when you manage several locations.

Request

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

Example response

{
  "spaces": [
    {
      "space_id": "sp_01",
      "name": "Private Room"
    },
    {
      "space_id": "sp_02",
      "name": "Patio"
    }
  ]
}

POST https://cotlet.dev/api/v1/perfect-venue/get_events_report

Returns the rows of the Events report, with the filters of a custom view: event status, venue, event owner, event date and created date. Use created dates to count new leads in a week and the status filter to count confirmed events. Lost events come back only when status is lost, with the lost reason.

Parameters

Parameters: get_events_report
NameTypeDescription
status enum lead, qualified, proposal_sent, confirmed, balance_due, completed or lost.
venue_id string Limit to one venue.
owner string Event owner, a team member email.
event_from date Event date on or after this date.
event_to date Event date on or before this date.
created_from date Created on or after this date.
created_to date Created on or before this date.
cursor string Next page cursor from the previous call.

Request

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

Example response

{
  "rows": [
    {
      "event_id": "ev_8812",
      "name": "Smith rehearsal dinner",
      "status": "confirmed",
      "created_at": "2026-10-02",
      "start_date": "2026-11-14",
      "owner": "maria@example.com",
      "total": 4800
    },
    {
      "event_id": "ev_8830",
      "name": "Lee birthday",
      "status": "lead",
      "created_at": "2026-10-08",
      "start_date": "2026-12-05",
      "owner": "maria@example.com",
      "total": 0
    }
  ],
  "count": 2,
  "next_cursor": null
}

Create lead

write

POST https://cotlet.dev/api/v1/perfect-venue/create_lead

Adds an event in the Lead status, the status every contact-form inquiry starts in, with the contact, date, time, guest count and spaces you give. It sends nothing to the guest and is undone with set_event_status lost, so it runs without asking first. Perfect Venue may still run your automated emails for the Lead stage.

Parameters

Parameters: create_lead
NameTypeDescription
first_name required string Contact first name.
last_name string Contact last name.
email required string Contact email.
phone string Contact phone.
start_date date Requested date.
start_time string Start time, HH:MM.
end_time string End time, HH:MM.
group_size integer Expected number of guests.
event_type string Event type as named in your account.
spaces array Space IDs from list_spaces.
message string Anything else from the inquiry.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/perfect-venue/create_lead \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"first_name":"Alex","last_name":"Client","email":"client@example.com","start_date":"2026-11-14","start_time":"18:00","end_time":"22:00","group_size":40,"event_type":"Birthday","message":"Birthday dinner, needs a private room."}'
Python
result = client.call("perfect-venue", "create_lead", {"first_name":"Alex","last_name":"Client","email":"client@example.com","start_date":"2026-11-14","start_time":"18:00","end_time":"22:00","group_size":40,"event_type":"Birthday","message":"Birthday dinner, needs a private room."})
Node.js
const result = await cotlet.call('perfect-venue', 'create_lead', {"first_name":"Alex","last_name":"Client","email":"client@example.com","start_date":"2026-11-14","start_time":"18:00","end_time":"22:00","group_size":40,"event_type":"Birthday","message":"Birthday dinner, needs a private room."});
CLI
cotlet call perfect-venue create_lead --data '{"first_name":"Alex","last_name":"Client","email":"client@example.com","start_date":"2026-11-14","start_time":"18:00","end_time":"22:00","group_size":40,"event_type":"Birthday","message":"Birthday dinner, needs a private room."}'

Example response

{
  "event_id": "ev_8841",
  "status": "lead",
  "start_date": "2026-11-14",
  "group_size": 40,
  "contact": {
    "name": "Alex Client",
    "email": "client@example.com"
  }
}

Update event

write

POST https://cotlet.dev/api/v1/perfect-venue/update_event

Changes the fields you pass and leaves the rest. It does not change the proposal items, prices or the status; use set_event_status for the status. It reaches no guest and is undone by calling it again with the old values, so it runs without asking first.

Parameters

Parameters: update_event
NameTypeDescription
event_id required string Event ID from list_events.
name string Event name.
start_date date New date.
start_time string Start time, HH:MM.
end_time string End time, HH:MM.
group_size integer Number of guests.
spaces array Space IDs from list_spaces.
event_type string Event type as named in your account.
owner string Event owner, a team member email.
internal_notes string Internal notes of the event.

Request

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

Example response

{
  "event_id": "ev_8812",
  "status": "confirmed",
  "group_size": 60,
  "updated": [
    "group_size"
  ]
}

Set event status

write Confirm

POST https://cotlet.dev/api/v1/perfect-venue/set_event_status

Sets the status of one event: lead, qualified, proposal_sent, confirmed, balance_due, completed or lost. Perfect Venue asks for a canceled reason when an event is moved to lost, so reason is required then. Statuses can trigger your automated emails, which are set by event stage, so a change can reach the guest. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: set_event_status
NameTypeDescription
event_id required string Event ID from list_events.
status required enum lead, qualified, proposal_sent, confirmed, balance_due, completed or lost.
reason string Canceled reason. Required when status is lost.

Request

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

Example response

{
  "event_id": "ev_8830",
  "status": "qualified",
  "previous_status": "lead"
}

Send proposal

write Confirm

POST https://cotlet.dev/api/v1/perfect-venue/send_proposal

Sends the current proposal of one event to its contact. Perfect Venue then moves the event to Proposal Sent by itself. The guest can change their menu choices only until the proposal locks. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_proposal
NameTypeDescription
event_id required string Event ID from list_events.
message string Short note to the guest with the proposal.

Request

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

Example response

{
  "event_id": "ev_8812",
  "status": "proposal_sent",
  "sent_to": "jane@example.com",
  "sent_at": "2026-10-11T09:30:00+02:00"
}

Send email

write Confirm

POST https://cotlet.dev/api/v1/perfect-venue/send_email

Sends one email to the contact of an event from the inbox, so the reply lands in the same thread. With template_id, Perfect Venue fills in the event details of the Personalize fields. Give body or template_id. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_email
NameTypeDescription
event_id required string Event ID from list_events.
template_id string Template from list_email_templates.
subject string Subject line.
body string Email text. Required without template_id.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/perfect-venue/send_email \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"ev_8830","template_id":"tpl_followup","subject":"Still looking at Saturday 5 Dec?"}'
Python
result = client.call("perfect-venue", "send_email", {"event_id":"ev_8830","template_id":"tpl_followup","subject":"Still looking at Saturday 5 Dec?"})
Node.js
const result = await cotlet.call('perfect-venue', 'send_email', {"event_id":"ev_8830","template_id":"tpl_followup","subject":"Still looking at Saturday 5 Dec?"});
CLI
cotlet call perfect-venue send_email --data '{"event_id":"ev_8830","template_id":"tpl_followup","subject":"Still looking at Saturday 5 Dec?"}'

Example response

{
  "event_id": "ev_8830",
  "status": "sent",
  "to": "lee@example.com",
  "subject": "Still looking at Saturday 5 Dec?",
  "sent_at": "2026-10-11T09:32:00+02:00"
}

Log offline payment

write Confirm

POST https://cotlet.dev/api/v1/perfect-venue/log_offline_payment

Logs a payment made outside Perfect Venue on one event, with amount, method, status and date, as Add payment, Offline payment does in the app. It charges no one, but the amount deducts from the total due on the proposal and shows in your payment reports. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: log_offline_payment
NameTypeDescription
event_id required string Event ID from list_events.
amount required number Amount paid.
method required string How it was paid, for example cash or check.
status string Payment status as named in your account.
paid_on date Date it was paid.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/perfect-venue/log_offline_payment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","amount":1,"method":"method"}'
Python
result = client.call("perfect-venue", "log_offline_payment", {"event_id":"event_8c41d2","amount":1,"method":"method"})
Node.js
const result = await cotlet.call('perfect-venue', 'log_offline_payment', {"event_id":"event_8c41d2","amount":1,"method":"method"});
CLI
cotlet call perfect-venue log_offline_payment --data '{"event_id":"event_8c41d2","amount":1,"method":"method"}'

Example response

{
  "payment_id": "pay_3302",
  "event_id": "ev_8812",
  "type": "offline",
  "amount": 800,
  "method": "check",
  "paid_on": "2026-10-09",
  "balance_due": 3000
}

Refund payment

write Confirm

POST https://cotlet.dev/api/v1/perfect-venue/refund_payment

Refunds a payment that was made online, in full or in part, with a reason. Offline payments cannot be refunded here; they go back by the original payment method. Perfect Venue notes that a refund can take 5 to 7 business days to reach the guest, and takes the money from your connected payment account or bank account. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: refund_payment
NameTypeDescription
payment_id required string Online payment ID from list_payments.
amount number Amount to refund. Omit for a full refund.
reason required string Reason for the refund.

Request

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

Example response

{
  "payment_id": "pay_3301",
  "event_id": "ev_8812",
  "refunded": 1000,
  "refund_type": "full",
  "status": "refunded"
}