Mettere in coda un job
# Enqueue an async job
curl -X POST https://api.knogin.com/v1/jobs \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8b9d8a2e-4a8c-4a7e-8a2e-4a8c4a7e8a2e" \
-d '{
"kind": "intelligence.enrich.bulk",
"payload": { "profile_ids": ["p1", "p2"] },
"callback_url": "https://partner.example.com/argus-webhook",
"secrecy_level": "standard"
}'
# 201 Created
# {
# "id": "01HFXY...",
# "kind": "intelligence.enrich.bulk",
# "status": "queued",
# "created_at": "2026-05-08T12:00:00Z",
# "trace_id": "0af7651916cd43dd8448eb211c80319c"
# }
Stato, risultato e payload del webhook
# GET /v1/jobs/{id} while running
{
"id": "01HFXY...",
"kind": "intelligence.enrich.bulk",
"status": "running",
"progress_pct": 42,
"created_at": "2026-05-08T12:00:00Z",
"updated_at": "2026-05-08T12:00:30Z",
"completed_at": null,
"error": null,
"trace_id": "0af7651916cd43dd8448eb211c80319c"
}
# GET /v1/jobs/{id}/result after success
{
"id": "01HFXY...",
"result_ref": "r2://argus-jobs/results/01HFXY.json",
"signed_url": "https://r2-presigned-url..."
}
# GET /v1/jobs?kind=intelligence.enrich.bulk&status=running&limit=50
{
"jobs": [ /* job objects */ ],
"next_cursor": "eyJjcmVhdGVkX2F0IjoiLi4uIn0=",
"total_count": 1234
}
Consegna del webhook
# Argus -> partner.example.com/argus-webhook
POST /argus-webhook HTTP/1.1
Host: partner.example.com
Content-Type: application/json
X-Argus-Trace-ID: 0af7651916cd43dd8448eb211c80319c
X-Argus-Job-ID: 01HFXY...
X-Argus-Signature: sha256=<hex of HMAC-SHA256(canonical_json_body, partner_secret)>
{
"id": "01HFXY...",
"kind": "intelligence.enrich.bulk",
"status": "succeeded",
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"result_ref": "r2://argus-jobs/results/01HFXY.json"
}
Verificare la firma del webhook
// Node.js (Express): verify X-Argus-Signature on the raw body
import crypto from 'node:crypto';
function verifyArgusSignature(rawBody, headerValue, sharedSecret) {
const expectedHex = crypto
.createHmac('sha256', sharedSecret)
.update(rawBody)
.digest('hex');
const expected = Buffer.from(`sha256=${expectedHex}`, 'utf8');
const provided = Buffer.from(headerValue ?? '', 'utf8');
if (provided.length !== expected.length) return false;
return crypto.timingSafeEqual(provided, expected);
}
# Python (Flask): canonical-body verification
import hmac, hashlib, json
def verify_argus_signature(raw_body: bytes, header_value: str, shared_secret: bytes) -> bool:
expected = "sha256=" + hmac.new(shared_secret, raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header_value or "")
# Argus computes the signature over the canonical JSON body it sent:
# canonical = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
# sig = hmac.new(secret, canonical, hashlib.sha256).hexdigest()
# header = f"sha256={sig}"