API — Webhooks
Înregistrare webhooks și primirea notificărilor în timp real pentru licitații noi prin API-ul public SCOPO Intelligence v1.
API — Webhooks
Disponibil: plan Consultant · Autentificare: API Key
Webhooks-urile îți permit să primești notificări automate când apare o licitație nouă potrivită pentru un client, fără polling manual.
Cost credite: 0 (push-ul este inclus în abonamentul Consultant)
Înregistrare webhook
POST /api/v1/webhooks
POST /api/v1/webhooks
Authorization: Bearer scopo_<cheie>
Content-Type: application/json
{
"url": "https://crm.firma.ro/webhooks/scopo",
"secret": "secret_de_minim_32_caractere_here",
"events": ["tender.matched"]
}
Câmpuri:
| Câmp | Tip | Obligatoriu | Descriere |
|---|---|---|---|
url | string | ✓ | URL HTTPS la care SCOPO face POST |
secret | string | ✓ | Secret pentru semnătura HMAC (min 32 caractere) |
events | string[] | ✓ | Lista de events (vezi tabelul de mai jos) |
Events disponibile:
| Event | Declanșat când |
|---|---|
tender.matched | O licitație nouă atinge pragul de scor al unui watchlist |
Răspuns (201 Created):
{
"webhook_id": "uuid-webhook",
"url": "https://crm.firma.ro/webhooks/scopo",
"events": ["tender.matched"],
"created_at": "2026-06-19T10:00:00Z"
}
Secretul NU este stocat în plaintext. Dacă îl pierzi, șterge webhook-ul și creează unul nou.
Limită: maximum 5 webhooks active per tenant. La depășire: 422 WEBHOOK_LIMIT_EXCEEDED.
Listare webhooks active
GET /api/v1/webhooks
GET /api/v1/webhooks
Authorization: Bearer scopo_<cheie>
{
"data": [
{
"webhook_id": "uuid-webhook",
"url": "https://crm.firma.ro/webhooks/scopo",
"events": ["tender.matched"],
"active": true,
"created_at": "2026-06-19T10:00:00Z"
}
]
}
Ștergere webhook
DELETE /api/v1/webhooks/:id
DELETE /api/v1/webhooks/uuid-webhook
Authorization: Bearer scopo_<cheie>
Răspuns (200):
{
"webhook_id": "uuid-webhook",
"active": false,
"deleted_at": "2026-06-19T10:05:00Z"
}
Dezactivarea este imediată. Job-urile de livrare deja în curs sunt finalizate cu status webhook_deleted.
Formatul payload-ului primit
SCOPO face un POST la URL-ul tău cu:
Headers:
Content-Type: application/json
X-SCOPO-Signature: sha256=a1b2c3d4e5f6...
X-SCOPO-Event: tender.matched
X-SCOPO-Timestamp: 1718698225
X-SCOPO-Delivery: uuid-livrare-unica
Body:
{
"event": "tender.matched",
"company_id": "uuid-companie",
"tender": {
"id": "uuid-licitatie",
"title": "Servicii de mentenanță software pentru...",
"score": 87,
"verdict": "GO",
"cpv_codes": ["72212000-4"],
"deadline": "2026-08-15T23:59:59Z",
"estimated_value_ron": 450000,
"source_url": "https://sicap-prod.e-licitatie.ro/..."
},
"timestamp": "2026-06-19T10:23:45Z"
}
Verificarea semnăturii HMAC
Verifică mereu semnătura pentru a te asigura că payload-ul vine de la SCOPO:
const crypto = require('crypto')
function verifySignature(rawBody, timestamp, receivedSignature, secret) {
const payload = `${timestamp}.${rawBody}`
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex')
return `sha256=${expected}` === receivedSignature
}
// În handler-ul tău webhook:
app.post('/webhooks/scopo', (req, res) => {
const signature = req.headers['x-scopo-signature']
const timestamp = req.headers['x-scopo-timestamp']
const rawBody = req.rawBody // string, nu parsed JSON
if (!verifySignature(rawBody, timestamp, signature, process.env.SCOPO_WEBHOOK_SECRET)) {
return res.status(401).send('Semnătură invalidă')
}
// Procesează payload-ul
const event = req.body
console.log('Licitație nouă:', event.tender.title, '— scor:', event.tender.score)
res.status(200).send('OK')
})
Returnează întotdeauna 2xx dacă ai primit și procesat payload-ul. SCOPO consideră orice alt cod drept eșec și reîncercă.
Politica de retry
| Attempt | Delay |
|---|---|
| 1 | imediat |
| 2 | 30 secunde |
| 3 | 5 minute |
| 4 (final) | 30 minute |
Dacă al 4-lea attempt eșuează, livrarea este marcată failed și primești un email de notificare.
Timeout per request: 30 secunde — asigură-te că handler-ul răspunde rapid; procesează async dacă operația durează.
Monitorizare livrări
Ultimele 10 livrări (cu status, timestamp și HTTP response code) sunt vizibile în Settings → API → Utilizare API.
Dintr-o livrare eșuată poți declanșa manual un nou attempt din dashboard.
Erori frecvente
| Cod | Eroare | Cauză |
|---|---|---|
| 401 | API_KEY_INVALID | Cheie lipsă sau invalidă |
| 403 | PLAN_UPGRADE_REQUIRED | Plan < Consultant |
| 422 | WEBHOOK_LIMIT_EXCEEDED | Deja 5 webhooks active per tenant |
| 400 | — | URL invalid sau secret prea scurt |
Vezi și
- Autentificare API Key
- Licitații API — polling alternativ
- Erori API — referință completă