API Documentation
Qluro Public API & SDK
Generate invoices programmatically, manage webhooks, and integrate Qluro into your stack in minutes.
Quick Start
Install the SDK and create your first invoice in 3 lines of code.
bash
npm install qlurojavascript
import { Qluro } from 'qluro';
const qluro = new Qluro('your_api_key');
// Create an invoice
const invoice = await qluro.invoices.create({
client_name: 'Acme Corp',
amount: 1500,
description: 'Web development — March 2026',
client_email: 'billing@acme.com',
currency: 'EUR',
});
console.log(invoice.invoice_number); // "API-2026-X7K2P9"
console.log(invoice.id); // UUIDSDK Reference
The SDK wraps the REST API with typed methods and automatic error handling.
Initialize
javascript
import { Qluro } from 'qluro';
// Initialize with your API key
const qluro = new Qluro('qluro_live_xxxxxxxxxxxx', {
baseUrl: 'https://ycergavwrjevjvqturgg.supabase.co/functions/v1/public-api', // optional, defaults to production
});List Invoices
javascript
const { invoices, count } = await qluro.invoices.list();
// Returns up to 100 invoices, newest first
invoices.forEach(inv => {
console.log(`${inv.invoice_number}: ${inv.amount}€ — ${inv.status}`);
});Create Invoice
javascript
const { invoice, payment_url } = await qluro.invoices.create({
client_name: 'Startup Studio', // required, max 255 chars
amount: 2500, // required, positive number
description: 'UI/UX Design Sprint', // required, max 1000 chars
client_email: 'pay@startup.io', // optional
currency: 'EUR', // optional, default: EUR
create_payment_link: true, // optional, adds a secure payment link (1.5% fee)
});
// Send the payment link to your client
if (payment_url) {
await sendEmail(invoice.client_email, payment_url);
}Get Invoice
javascript
const { invoice } = await qluro.invoices.get('uuid-of-invoice');
console.log(invoice.status); // "generated" | "sent" | "paid" | "reminded"
console.log(invoice.payment_link_url); // Payment URL if createdWebhooks
Get notified in real-time when invoice statuses change.
Subscribe to Events
javascript
const { webhook, secret } = await qluro.webhooks.create({
url: 'https://yourapp.com/api/qluro-webhook',
events: ['invoice.created', 'invoice.paid'],
});
// ⚠️ Save this secret — it won't be shown again
console.log('Webhook secret:', secret);Verify Webhook Signature
javascript
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return signature === `sha256=${expected}`;
}
// In your webhook handler:
app.post('/api/qluro-webhook', (req, res) => {
const sig = req.headers['x-qluro-signature'];
if (!verifyWebhook(req.body, sig, process.env.QLURO_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { event, data } = req.body;
switch (event) {
case 'invoice.paid':
console.log(`Invoice ${data.invoice_number} paid: ${data.amount}€`);
break;
case 'invoice.created':
console.log(`New invoice: ${data.invoice_number}`);
break;
}
res.json({ received: true });
});Event Types
invoice.createdA new invoice was generatedinvoice.paidInvoice was paidinvoice.sentInvoice was emailed to clientinvoice.remindedPayment reminder was sentREST API (cURL)
Don't want to use the SDK? Call the API directly with any HTTP client.
Authentication
Pass your API key in the x-api-key header.
List Invoices
bash
curl -X GET 'https://ycergavwrjevjvqturgg.supabase.co/functions/v1/public-api/invoices' \
-H 'x-api-key: your_api_key'Create Invoice
bash
curl -X POST 'https://ycergavwrjevjvqturgg.supabase.co/functions/v1/public-api/invoices' \
-H 'x-api-key: your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"client_name": "Acme Corp",
"amount": 1500,
"description": "Web development — March 2026",
"client_email": "billing@acme.com",
"currency": "EUR"
}'Get Invoice
bash
curl -X GET 'https://ycergavwrjevjvqturgg.supabase.co/functions/v1/public-api/invoices/INVOICE_UUID' \
-H 'x-api-key: your_api_key'SDK Source Code
The full SDK source — copy-paste it or publish it as an npm package.
typescript
// qluro.ts — Qluro JavaScript SDK
interface QluroOptions {
baseUrl?: string;
}
interface CreateInvoiceParams {
client_name: string;
amount: number;
description: string;
client_email?: string;
currency?: string;
create_payment_link?: boolean;
}
interface Invoice {
id: string;
invoice_number: string;
client_name: string;
client_email: string | null;
amount: number;
description: string | null;
currency: string;
status: string;
payment_link_url: string | null;
created_at: string;
}
interface WebhookParams {
url: string;
events?: string[];
}
class QluroError extends Error {
status: number;
constructor(message: string, status: number) {
super(message);
this.name = 'QluroError';
this.status = status;
}
}
export class Qluro {
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, options?: QluroOptions) {
this.apiKey = apiKey;
this.baseUrl = options?.baseUrl || 'https://ycergavwrjevjvqturgg.supabase.co/functions/v1/public-api';
}
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
const res = await fetch(`${this.baseUrl}/${path}`, {
method,
headers: {
'x-api-key': this.apiKey,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
});
const data = await res.json();
if (!res.ok) throw new QluroError(data.error || 'Unknown error', res.status);
return data as T;
}
invoices = {
list: () => this.request<{ invoices: Invoice[]; count: number }>('GET', 'invoices'),
get: (id: string) => this.request<{ invoice: Invoice }>('GET', `invoices/${id}`),
create: (params: CreateInvoiceParams) =>
this.request<{ invoice: Invoice; payment_url?: string }>('POST', 'invoices', params),
};
webhooks = {
list: () => this.request<{ webhooks: any[]; count: number }>('GET', 'webhooks'),
create: (params: WebhookParams) =>
this.request<{ webhook: any; secret: string }>('POST', 'webhooks', params),
delete: (id: string) => this.request<{ message: string }>('DELETE', `webhooks/${id}`),
};
}Rate Limits & Plans
| Feature | Starter (9€) | Pro (19€) | Comptable (99€) |
|---|---|---|---|
| API Access | ✅ | ✅ | ✅ |
| Rate Limit | 60/min | 60/min | Unlimited |
| Payment Links | ❌ | 1.5% fee | 1.5% fee |
| Webhooks | ❌ | ❌ | ✅ |
| FEC/DATEV Export | ❌ | ❌ | ✅ |
| Multi-user | ❌ | ❌ | ✅ |
Error Codes
400Bad request — missing or invalid fields401Missing x-api-key header403Invalid or inactive API key404Resource not found429Rate limit exceeded — retry after 60s500Internal server error