API v1 · planul Pro și peste
API Emisar APP
Un API REST simplu, cu JSON, ca să legi Emisar APP de CRM, de platforma de bilete, de turnichete sau de sistemul intern. Toate rutele sunt sub https://emisar.ro/api/v1/ext. Cheile se creează în consolă, la Setări → API.
Autentificare
Fiecare cerere poartă cheia organizației în antetul Authorization. Cheia are prefixul mk_live_, se afișează o singură dată la creare și poate fi revocată oricând.
curl https://emisar.ro/api/v1/ext/events \
-H "Authorization: Bearer mk_live_XXXXXXXXXXXXXXXX"Evenimente
GET /ext/events — evenimentele organizației, cu slug, nume, stare, date, oraș, locație și plan.
{
"ok": true,
"events": [
{ "id": "…", "slug": "forum-2026", "name": "Forum 2026", "status": "PUBLISHED",
"startsAt": "2026-10-12T07:00:00.000Z", "endsAt": "2026-10-12T16:00:00.000Z",
"city": "București", "venue": "JW Marriott", "timezone": "Europe/Bucharest",
"plan": "PRO", "url": "https://emisar.ro/e/forum-2026" }
]
}Participanți
GET /ext/events/{slug}/participants?page=1&limit=100 — lista paginată (max 200 pe pagină), cu email, nume, companie, funcție, cod de bilet, sursă, check-in și dacă profilul e completat.
POST /ext/events/{slug}/participants — creează sau actualizează până la 500 de participanți per cerere, după email. ticketCode este codul de pe bilet: cu el, biletul lor se scanează direct cuEmisar APP la ușă. cancelled: true scoate participantul din listă (soft-delete, doar dacă a venit din API).
curl -X POST https://emisar.ro/api/v1/ext/events/forum-2026/participants \
-H "Authorization: Bearer mk_live_…" -H "Content-Type: application/json" \
-d '{
"participants": [
{ "email": "[email protected]", "name": "Ana Pop", "company": "Firma SRL",
"jobTitle": "CEO", "ticketCode": "EB-1234567890", "externalId": "ord_88" },
{ "email": "[email protected]", "cancelled": true }
]
}'
# răspuns
{ "ok": true, "created": 1, "updated": 0, "removed": 1, "skippedCap": 0, "skippedInvalid": 0 }Plafonul planului se respectă: peste plafon, participanții noi sunt raportați în skippedCap.
Check-in-uri
GET /ext/events/{slug}/checkins?since=2026-10-12T07:00:00Z — check-in-urile în ordine cronologică (participant, email, cod bilet, metodă, oră). Pentru sincronizare continuă, reține ultimul checkedInAt și trimite-l ca since.
POST /ext/events/{slug}/checkins — check-in dintr-un sistem extern (turnichet, aplicația voastră de scanare), după ticketCode, email sau externalId.
curl -X POST https://emisar.ro/api/v1/ext/events/forum-2026/checkins \
-H "Authorization: Bearer mk_live_…" -H "Content-Type: application/json" \
-d '{ "ticketCode": "EB-1234567890" }'
{ "ok": true, "participantId": "…", "email": "[email protected]", "status": "checked_in", "checkedInAt": "…" }
# a doua oară: "status": "already_checked_in"Webhook-uri
Din Setări → Webhook-uri înregistrezi un URL https și primești un POST JSON la checkin.created, participant.created și participant.updated. Reîncercăm de 6 ori (2, 4, 8… minute) până primim 2xx.
POST https://sistemul-tau.ro/webhook
X-Webhook-Event: checkin.created
X-Webhook-Delivery: dlv_…
X-Webhook-Signature: t=1760000000,v1=<hex hmac-sha256(secret, "<t>.<body>")>
{ "id": "dlv_…", "type": "checkin.created", "createdAt": "…",
"data": { "eventSlug": "forum-2026", "participantId": "…", "method": "qr", "checkedInAt": "…" } }Verificare în Node.js:
const [t, v1] = sig.split(',').map((p) => p.split('=')[1]);
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'))
&& Math.abs(Date.now() / 1000 - Number(t)) < 300;Bilete: Eventbrite, Oveit, iabilet
Nu vindem bilete; le sincronizăm. În consolă, la Setări eveniment → Bilete, conectezi platforma și cumpărătorii apar ca participanți cu codul biletului. Sincronizare la 5 minute, plus instant dacă adaugi URL-ul nostru de webhook în platforma de bilete.
- Eventbrite — token privat (Account Settings → Developer Links → API Keys) + ID-ul evenimentului. Codul de bare al biletului devine codul scanabil.
- Oveit — email + parola contului de organizator, folosite o singură dată pentru token; participanții vin din formularele de înregistrare (nume, email), cu
ticket_code. - iabilet — fără API public: exportă CSV-ul de vânzări și importă-l la Participanți; coloana „cod bilet” face biletul scanabil.
Orice altă platformă poate folosi POST /participants cu ticketCode.
Erori și limite
401 api_key_required / api_key_invalid— lipsește sau e revocată cheia.402 upgrade_required— evenimentul nu e pe un plan cu API.404 event_not_found / participant_not_found.400 batch_too_large— peste 500 de participanți într-o cerere.- Limită: 1.200 de cereri pe minut per IP. Răspunsurile sunt JSON, datele în UTC (ISO 8601).