Skip to main content

Node.js SDK

Official Node.js/TypeScript SDK for the MonCréneau API, published on npm.

Installation​

npm install @moncreneau/api
# or
yarn add @moncreneau/api
# or
pnpm add @moncreneau/api

Configuration​

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

CommonJS:

const { default: Moncreneau } = require('@moncreneau/api');

const client = new Moncreneau('YOUR_API_KEY');

With environment variables:

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau(process.env.MONCRENEAU_API_KEY);

List departments​

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

async function listDepartments() {
try {
const departments = await client.departments.list();

departments.forEach(dept => {
console.log(`ID: ${dept.id} - ${dept.name}`);
});
} catch (error) {
console.error('Error:', error.message);
}
}

listDepartments();

Create an appointment​

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

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

console.log('✅ Appointment created!');
console.log('ID:', appointment.id);
console.log('QR Code:', appointment.qrCode);
console.log('Status:', appointment.status);

} catch (error) {
if (error.code === 'INSUFFICIENT_CREDITS') {
console.error('❌ Insufficient credits:', error.message);
} else {
console.error('❌ Error:', error.message);
}
}
}

createAppointment();

Check slot availability​

The backend checks a single slot (dateTime), not a date range.

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

async function checkAvailability() {
try {
const availability = await client.departments.getAvailability(
'5',
'2026-02-15T10:00:00'
);

if (availability.available) {
console.log('✅ Slot available!');
console.log('Remaining slots:', availability.remainingSlots);
} else {
console.log('❌ Slot unavailable');
console.log('Reason:', availability.unavailabilityReason);
}
} catch (error) {
console.error('Error:', error.message);
}
}

checkAvailability();

Cancel an appointment​

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

async function cancelAppointment(appointmentId) {
try {
await client.appointments.cancel(appointmentId);
console.log('✅ Appointment cancelled, 1 credit refunded');
} catch (error) {
console.error('❌ Error:', error.message);
}
}

cancelAppointment('123');

Express integration​

import express from 'express';
import Moncreneau from '@moncreneau/api';

const app = express();
app.use(express.json());

const client = new Moncreneau(process.env.MONCRENEAU_API_KEY);

// Create an appointment
app.post('/appointments', async (req, res) => {
try {
const { departmentId, dateTime, name } = req.body;

const appointment = await client.appointments.create({
departmentId,
dateTime,
name
});

res.status(201).json(appointment);
} catch (error) {
if (error.code === 'INSUFFICIENT_CREDITS') {
return res.status(402).json({ error: error.message });
}
res.status(error.statusCode || 500).json({ error: error.message });
}
});

// Check slot availability
app.get('/departments/:id/availability', async (req, res) => {
try {
const { id } = req.params;
const { dateTime } = req.query;

const availability = await client.departments.getAvailability(id, dateTime);

res.json(availability);
} catch (error) {
res.status(error.statusCode || 500).json({ error: error.message });
}
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Error handling​

There is only one error class, MoncreneauError — the business error code is available via .code:

import Moncreneau, { MoncreneauError } from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

try {
const appointment = await client.appointments.create(data);
} catch (error) {
if (error instanceof MoncreneauError) {
switch (error.code) {
case 'INSUFFICIENT_CREDITS':
console.error('Insufficient credits:', error.message);
break;
case 'VALIDATION_ERROR':
console.error('Validation:', error.details);
break;
case 'INVALID_API_KEY':
console.error('Invalid API key');
break;
default:
console.error(`Error ${error.code} (HTTP ${error.statusCode}):`, error.message);
}
} else {
console.error('Network error:', error);
}
}

Advanced configuration​

import Moncreneau from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY', {
baseUrl: 'https://mc-prd.duckdns.org/api/v1',
timeout: 30000, // 30 seconds
maxRetries: 3
});

Webhook verification​

verifyWebhookSignature is a static method on the Moncreneau class, not an instance method:

import express from 'express';
import Moncreneau from '@moncreneau/api';

const app = express();

app.post('/webhooks/moncreneau', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-moncreneau-signature'];
const payload = req.body.toString('utf8');

const isValid = Moncreneau.verifyWebhookSignature(
payload,
signature,
process.env.WEBHOOK_SECRET
);

if (!isValid) {
return res.status(401).send('Invalid signature');
}

const event = JSON.parse(payload);
console.log('Event:', req.headers['x-moncreneau-event'], event);

res.json({ received: true });
});

See Webhook Security for the signature format details.

TypeScript​

The SDK is written in TypeScript and exports all its types:

import Moncreneau, {
Department,
Appointment,
CreateAppointmentRequest,
SlotAvailability
} from '@moncreneau/api';

const client = new Moncreneau('YOUR_API_KEY');

async function example(): Promise<void> {
const departments: Department[] = await client.departments.list();

const request: CreateAppointmentRequest = {
departmentId: 5,
dateTime: '2026-02-15T10:00:00',
name: 'Amadou Diallo'
};

const appointment: Appointment = await client.appointments.create(request);
}