Documentation

Send events to Pilot-Biz

An event is a business fact: a payment received, an order, a contact request, a booking, an incident. Pilot-Biz sorts it, shows it in the dashboard, counts it in finances if it carries an amount, and alerts the team if needed. No imposed schema: send your fields, and Pilot-Biz recognises the usual ones (amount, customer, email, phone, message).

The API itself is language-neutral. Field names such as montant or telephone are accepted alongside their English equivalents.

Authentication

Each business has its own keys, created from its page → Connect → Custom website. A key is valid for that business only and can be revoked in one click.

Authorization: Bearer pb_live_…

Send an event

POST https://pilot-biz.fr/api/v1/events Content-Type: application/json
FieldTypeDescription
typetext, requiredType identifier: payment_received, order, quote_request… Free-form; Pilot-Biz learns each new type.
leveltextlow, medium, high or critical (also accepted: basse, moyenne, haute, urgent). Otherwise inferred from the type.
dataobjectYour fields. Recognised: amount/montant/total, currency/devise, name/client, email, phone/telephone, message.
titletextDisplayed title (otherwise the type’s label).
idtextUnique identifier on your side: sending again with the same id is ignored (no duplicates).
amount, currencynumber, ISO codeExplicit amount (takes priority over data). Default currency: the workspace’s.
occurred_atISO 8601 dateActual date of the event (otherwise: now).

Response: 201 { "ok": true, "id": "…" }, or 200 with "duplicate": true if the id has already been received.

Levels and categories

  • low (Info): recorded and sorted automatically, no alert by default.
  • medium (To follow): appears under “To handle”.
  • high (Important) and critical (Urgent): at the top of the dashboard and notified on Telegram.

The category (sale, order, request, message, booking, review, sign-up, alert) is inferred from the type and can be adjusted in the business’s catalogue, as can whether the amount counts toward revenue. Tip: send only one type per payment into revenue (for example payment_received), not the matching order as well.

Examples

PHP

<?php // Put this in a shared file (e.g. config/pilotbiz.php). Key to set in .env: PILOTBIZ_KEY=pb_live_… function pilotbiz_event(string $type, array $data = [], string $level = 'medium', ?string $id = null): void { $key = getenv('PILOTBIZ_KEY') ?: ($_ENV['PILOTBIZ_KEY'] ?? ''); if (!$key || !function_exists('curl_init')) return; $ch = curl_init('https://pilot-biz.fr/api/v1/events'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 4, // never slows your site down CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $key], CURLOPT_POSTFIELDS => json_encode(['type' => $type, 'level' => $level, 'data' => $data, 'id' => $id]), ]); @curl_exec($ch); // on failure: silent, your site carries on curl_close($ch); } // Example, right after a paid order is saved: pilotbiz_event('paiement_recu', ['montant' => 25000, 'client' => 'Awa N.', 'commande' => 'CMD-1042'], 'medium', 'CMD-1042');

Node.js

// Node.js / Next.js (native fetch). .env: PILOTBIZ_KEY=pb_live_… export async function pilotbizEvent(type, data = {}, level = 'medium', id) { try { await fetch('https://pilot-biz.fr/api/v1/events', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.PILOTBIZ_KEY}` }, body: JSON.stringify({ type, level, data, id }), signal: AbortSignal.timeout(4000), }); } catch {} // never blocking } await pilotbizEvent('nouvelle_reservation', { client: 'Awa N.', nuits: 3, montant: 120000 });

Python

# Python (requests). Environment variable: PILOTBIZ_KEY=pb_live_… import os, requests def pilotbiz_event(type, data=None, level="medium", id=None): try: requests.post("https://pilot-biz.fr/api/v1/events", timeout=4, headers={"Authorization": f"Bearer {os.environ['PILOTBIZ_KEY']}"}, json={"type": type, "level": level, "data": data or {}, "id": id}) except Exception: pass # never blocking pilotbiz_event("demande_devis", {"nom": "Awa N.", "email": "awa@exemple.com", "message": "Site e-commerce"})

cURL

curl -X POST https://pilot-biz.fr/api/v1/events \ -H "Authorization: Bearer pb_live_…" \ -H "Content-Type: application/json" \ -d '{"type":"paiement_recu","level":"medium","data":{"montant":25000,"client":"Awa N."}}'

Universal webhook link

A link like https://pilot-biz.fr/api/hooks/pbh_… accepts webhooks from Shopify, WooCommerce, Stripe, Calendly, Typeform, Tally, as well as any JSON (Zapier, Make, n8n…). The provider is recognised from its headers; Stripe amounts are converted from cents. If you enter the provider’s signing secret, every call is verified (HMAC). For generic JSON: type (or event), level, data, id.

No-code forms

<script src="https://pilot-biz.fr/pb.js" data-key="pk_…" async></script>
  • Each submitted form becomes a request; the name comes from data-pb-name, the form’s title or the page’s.
  • Never read: passwords, cards, hidden fields, tokens. Sign-in forms are ignored. To exclude a form: data-pb-ignore.
  • Manual event: window.pilotbiz.track('booking', { name: 'Awa', guests: 4 }).
  • The pk_… key is public; it is locked to the first domain that uses it.

Inbound email

Each business can receive a forwarding address. Forwarded emails become “Email received” events (sender, subject, text). On the platform side, reception goes through an inbound email service (Cloudflare Email Routing, Postmark, Mailgun) that posts the message to /api/inbound/email/<key>.

Legacy format

Sites connected to the first version remain compatible:

POST https://pilot-biz.fr/api/ingest Authorization: Bearer <token> { "business_id": "…", "type_evenement": "paiement_recu", "urgence": "haute", "donnees": { "montant": 25000 } }

Errors and limits

  • 401 key missing, invalid or revoked · 400 invalid body (field details returned) · 413 body > 64 KB · 429 too many requests.
  • Limit: 300 events per minute per key (600 for a webhook link).
  • Good practice: a 4-second timeout on your side, errors silently ignored, the key kept in an environment variable.