Aller au contenu principal
    API Documentation

    Qluro Public API & SDK

    Generate invoices programmatically, manage webhooks, and integrate Qluro into your stack in minutes.

    Get your API Key

    Quick Start

    Install the SDK and create your first invoice in 3 lines of code.

    bash
    npm install qluro
    javascript
    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);             // UUID

    SDK 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 created

    Webhooks

    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 generated
    invoice.paidInvoice was paid
    invoice.sentInvoice was emailed to client
    invoice.remindedPayment reminder was sent

    REST 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

    FeatureStarter (9€)Pro (19€)Comptable (99€)
    API Access
    Rate Limit60/min60/minUnlimited
    Payment Links1.5% fee1.5% fee
    Webhooks
    FEC/DATEV Export
    Multi-user

    Error Codes

    400Bad request — missing or invalid fields
    401Missing x-api-key header
    403Invalid or inactive API key
    404Resource not found
    429Rate limit exceeded — retry after 60s
    500Internal server error

    Ready to integrate?

    Generate your API key and start creating invoices in minutes.