Skip to main content

Appointments Endpoints

Manage appointments: creation, retrieval, and cancellation.

Credits

Creating an appointment consumes 1 credit. Cancelling an appointment refunds 1 credit (handle the refund logic in your own code: see the note under DELETE /appointments/{id}).

PHP and Java SDKs

The PHP and Java examples below use the official SDK syntax — not yet published on Packagist/Maven Central (see PHP SDK and Java SDK). Node.js and Python are published and usable today.

POST /appointments​

Creates a new appointment. Automatically consumes 1 credit from your organization.

Optional fields
  • externalUserId: Your own system's identifier to match with your users
  • workerId: Staff/professional ID. Required only if the department has showAdminsInBooking=true

Request​

curl -X POST https://mc-prd.duckdns.org/api/v1/appointments \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"departmentId": 5,
"dateTime": "2026-02-15T10:00:00",
"name": "Amadou Diallo",
"workerId": 42,
"externalUserId": "customer_12345"
}'
Java
import com.moncreneau.Moncreneau;
import com.moncreneau.exceptions.MoncreneauException;
import java.util.Map;

Moncreneau client = new Moncreneau("your_api_key");

Map<String, Object> data = Map.of(
"departmentId", 5,
"dateTime", "2026-02-15T10:00:00",
"name", "Amadou Diallo",
"workerId", 42,
"externalUserId", "customer_12345"
);

try {
Map<String, Object> appointment = client.appointments.create(data);
System.out.println("Appointment created with ID: " + appointment.get("id"));
System.out.println("QR Code: " + appointment.get("qrCode"));
} catch (MoncreneauException e) {
if ("INSUFFICIENT_CREDITS".equals(e.getErrorCode())) {
System.err.println("Insufficient credits: " + e.getMessage());
}
}
Node.js
import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('your_api_key');

try {
const appointment = await client.appointments.create({
departmentId: 5,
dateTime: '2026-02-15T10:00:00',
name: 'Amadou Diallo',
workerId: 42,
externalUserId: 'customer_12345'
});

console.log(`Appointment created with ID: ${appointment.id}`);
console.log(`QR Code: ${appointment.qrCode}`);
} catch (error) {
if (error.code === 'INSUFFICIENT_CREDITS') {
console.error('Insufficient credits:', error.message);
}
}
PHP
<?php
use Moncreneau\Moncreneau;
use Moncreneau\Exceptions\MoncreneauException;

$client = new Moncreneau('your_api_key');

try {
$appointment = $client->appointments->create([
'departmentId' => 5,
'dateTime' => '2026-02-15T10:00:00',
'name' => 'Amadou Diallo',
'externalUserId' => 'customer_12345'
]);

echo "Appointment created with ID: {$appointment['id']}" . PHP_EOL;
echo "QR Code: {$appointment['qrCode']}" . PHP_EOL;
} catch (MoncreneauException $e) {
if ($e->getErrorCode() === 'INSUFFICIENT_CREDITS') {
echo "Insufficient credits: {$e->getMessage()}" . PHP_EOL;
}
}
Python
from moncreneau import Moncreneau, MoncreneauError

client = Moncreneau('your_api_key')

try:
appointment = client.appointments.create(
department_id=5,
date_time='2026-02-15T10:00:00',
name='Amadou Diallo',
worker_id=42,
external_user_id='customer_12345'
)

print(f"Appointment created with ID: {appointment['id']}")
print(f"QR Code: {appointment['qrCode']}")
except MoncreneauError as e:
if e.code == 'INSUFFICIENT_CREDITS':
print(f"Insufficient credits: {e.message}")

Response 201 - Success​

{
"id": 123,
"dateTime": "2026-02-15T10:00:00",
"status": "SCHEDULED",
"name": "Amadou Diallo",
"qrCode": "a1b2c3d4-...",
"departmentId": 5,
"departmentName": "General Consultation",
"externalUserId": "customer_12345",
"createdAt": "2026-01-21T09:30:00"
}

Response 402 - Insufficient Credits​

{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits to create appointment. Current: 0, Required: 1"
}
}

Response 400 - Bad Request​

{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body is invalid.",
"details": [
{ "field": "dateTime", "message": "must not be null" }
]
}
}

GET /appointments/{id}​

Retrieves an appointment's details by ID.

Request​

curl https://mc-prd.duckdns.org/api/v1/appointments/123 \
-H "X-API-Key: YOUR_API_KEY"
Java
import com.moncreneau.Moncreneau;
import java.util.Map;

Moncreneau client = new Moncreneau("your_api_key");
Map<String, Object> appointment = client.appointments.retrieve("123");

System.out.println("Status: " + appointment.get("status"));
System.out.println("Date: " + appointment.get("dateTime"));
System.out.println("Name: " + appointment.get("name"));
Node.js
import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('your_api_key');
const appointment = await client.appointments.retrieve('123');

console.log(`Status: ${appointment.status}`);
console.log(`Date: ${appointment.dateTime}`);
console.log(`Name: ${appointment.name}`);
PHP
<?php
use Moncreneau\Moncreneau;

$client = new Moncreneau('your_api_key');
$appointment = $client->appointments->retrieve('123');

echo "Status: {$appointment['status']}" . PHP_EOL;
echo "Date: {$appointment['dateTime']}" . PHP_EOL;
echo "Name: {$appointment['name']}" . PHP_EOL;
Python
from moncreneau import Moncreneau

client = Moncreneau('your_api_key')
appointment = client.appointments.retrieve('123')

print(f"Status: {appointment['status']}")
print(f"Date: {appointment['dateTime']}")
print(f"Name: {appointment['name']}")

Response 200​

{
"id": 123,
"dateTime": "2026-02-15T10:00:00",
"status": "SCHEDULED",
"name": "Amadou Diallo",
"qrCode": "a1b2c3d4-...",
"departmentId": 5,
"departmentName": "General Consultation",
"createdAt": "2026-01-21T09:30:00"
}

Response 404​

{
"error": {
"code": "APPOINTMENT_NOT_FOUND",
"message": "Appointment not found with id: 123"
}
}

GET /appointments​

Lists all appointments for your organization, with pagination and optional filters.

Available filters

You can filter by status, departmentId, externalUserId, startDate, endDate, and paginate with page and size.

Request​

curl -X GET "https://mc-prd.duckdns.org/api/v1/appointments?page=0&size=20&status=SCHEDULED" \
-H "X-API-Key: YOUR_API_KEY"
Java
import com.moncreneau.Moncreneau;
import java.util.Map;

Moncreneau client = new Moncreneau("your_api_key");

// Simple list
Map<String, Object> page = client.appointments.list(Map.of());

// With filters
Map<String, Object> filtered = client.appointments.list(Map.of(
"status", "SCHEDULED",
"departmentId", "5",
"externalUserId", "customer_12345",
"page", "0",
"size", "20"
));

System.out.println("Total: " + filtered.get("totalElements"));
Node.js
import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('your_api_key');

// Simple list
const page = await client.appointments.list();

// With filters
const filtered = await client.appointments.list({
page: 0,
size: 20,
status: 'SCHEDULED',
departmentId: '5',
externalUserId: 'customer_12345',
startDate: '2026-02-01T00:00:00',
endDate: '2026-02-28T23:59:59'
});

console.log(`Total: ${filtered.totalElements}`);
filtered.appointments.forEach(apt => {
console.log(`${apt.name} - ${apt.dateTime}`);
});
PHP
<?php
use Moncreneau\Moncreneau;

$client = new Moncreneau('your_api_key');

// Simple list
$page = $client->appointments->list();

// With filters
$filtered = $client->appointments->list([
'page' => 0,
'size' => 20,
'status' => 'SCHEDULED',
'departmentId' => 5,
'externalUserId' => 'customer_12345',
'startDate' => '2026-02-01T00:00:00',
'endDate' => '2026-02-28T23:59:59'
]);

echo "Total: {$filtered['totalElements']}" . PHP_EOL;
foreach ($filtered['appointments'] as $apt) {
echo "{$apt['name']} - {$apt['dateTime']}" . PHP_EOL;
}
Python
from moncreneau import Moncreneau

client = Moncreneau('your_api_key')

# Simple list
page = client.appointments.list()

# With filters
filtered = client.appointments.list(
page=0,
size=20,
status='SCHEDULED',
department_id='5',
external_user_id='customer_12345',
start_date='2026-02-01T00:00:00',
end_date='2026-02-28T23:59:59'
)

print(f"Total: {filtered['totalElements']}")
for apt in filtered['appointments']:
print(f"{apt['name']} - {apt['dateTime']}")

Query parameters​

ParameterTypeDefaultDescription
pageinteger0Page number (starts at 0)
sizeinteger20Items per page (max 100)
statusstring-Filter by status (SCHEDULED, COMPLETED, CANCELLED, MISSED)
departmentIdinteger-Filter by department ID
externalUserIdstring-Filter by your external user ID
startDatestring (ISO 8601)-Appointments after this date
endDatestring (ISO 8601)-Appointments before this date

Response 200​

{
"appointments": [
{
"id": 123,
"dateTime": "2026-02-15T10:00:00",
"status": "SCHEDULED",
"name": "Amadou Diallo",
"qrCode": "a1b2c3d4-...",
"departmentId": 5,
"departmentName": "General Consultation",
"externalUserId": "customer_12345",
"createdAt": "2026-01-21T09:30:00"
}
],
"page": 0,
"size": 20,
"totalElements": 45,
"totalPages": 3,
"isLast": false
}

DELETE /appointments/{id}​

Cancels (archives) an appointment.

Actual behavior

This endpoint archives the appointment — it does not change its status (which stays SCHEDULED), and does not automatically refund a credit today, unlike cancelling from the web dashboard. The response is a 200 with no body.

Request​

curl -X DELETE https://mc-prd.duckdns.org/api/v1/appointments/123 \
-H "X-API-Key: YOUR_API_KEY"
Java
import com.moncreneau.Moncreneau;

Moncreneau client = new Moncreneau("your_api_key");
client.appointments.cancel("123");
System.out.println("Appointment archived");
Node.js
import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('your_api_key');
await client.appointments.cancel('123');
console.log('Appointment archived');
PHP
<?php
use Moncreneau\Moncreneau;

$client = new Moncreneau('your_api_key');
$client->appointments->cancel('123');
echo "Appointment archived" . PHP_EOL;
Python
from moncreneau import Moncreneau

client = Moncreneau('your_api_key')
client.appointments.cancel('123')
print('Appointment archived')

Response 200​

Empty body.

Response 404​

{
"error": {
"code": "APPOINTMENT_NOT_FOUND",
"message": "Appointment not found with id: 123"
}
}

Error Handling​

All errors return a standardized envelope:

{
error: {
code: string; // Error code (e.g. INSUFFICIENT_CREDITS)
message: string; // Human-readable message
details?: Array<{ // Only present for validation errors (400)
field: string;
message: string;
}>;
}
}

Common error codes​

CodeHTTPDescription
INSUFFICIENT_CREDITS402Not enough credits to create an appointment
APPOINTMENT_NOT_FOUND404Appointment not found
VALIDATION_ERROR400Invalid request body (see details)
INVALID_DATE_FORMAT400Malformed date (startDate/endDate)
MISSING_API_KEY / INVALID_API_KEY401API key missing, invalid, or revoked
INSUFFICIENT_SCOPE403Insufficient scope for this operation
RATE_LIMIT_EXCEEDED429Requests-per-hour limit exceeded
INTERNAL_ERROR500Internal server error

See Error Handling for full details.