Unicorn Intelligence API
REST API over HTTPS with JSON bodies, for every plan. The OpenAPI 3.1 specification is at /openapi.json. Information tool: decisions and legal obligations remain with the customer; every item carries its source and date.
Authentication · Plans and limits · Errors · Screening · Dossiers · Monitoring · Webhooks · Examples
Authentication
An admin creates keys in the dashboard (API tab). Keys start with ui_live_, are shown once and are stored only as a SHA-256 hash. Several named keys can be active; revoke them individually.
curl https://intel.unicornprivate.com/v1/usage -H "Authorization: Bearer ui_live_..."
Plans and limits
Each endpoint works only if the service is in your plan (otherwise 403 plan_upgrade_required). Limits are applied automatically: names monitored (100, 1,000 or 10,000), dossiers per month (plus purchased single dossiers), countries or areas for regulatory monitoring, competitors and sectors, tender search profiles. GET /v1/usage returns modules, limits and usage. Rate limit: 600 requests per minute per account (429 too_many_requests).
Plans are bought on the pricing page or in the dashboard. Monthly: card only, renews automatically, cancel whenever you want. Annual: 10 months paid for 12, by card or by bank transfer (bank transfer only for annual plans). GET /v1/usage returns the plan ids below.
| Plan id | Includes | Month | Year |
|---|---|---|---|
screening_100 | Screening Base: Sanctions and counterparty screening, up to 100 names. | $1,500 | $15,000 |
screening_1k | Screening Business: Sanctions and counterparty screening, up to 1,000 names. | $2,500 | $25,000 |
screening_10k | Screening Enterprise: Sanctions and counterparty screening, up to 10,000 names. | $4,000 | $40,000 |
dossier_10 | Dossier 10: Dossiers on private companies, 10 per month. | $3,900 | $39,000 |
sector | Sector: Competitor and startup intelligence, 10 competitors and 3 sectors. | $2,000 | $20,000 |
regulation_3 | Regulation 3: Regulatory monitoring, 3 countries or areas. | $1,500 | $15,000 |
regulation_10 | Regulation 10: Regulatory monitoring, 10 countries or areas. | $3,500 | $35,000 |
tenders | Tenders: International public tenders, all portals, 5 search profiles. | $900 | $9,000 |
sanctions | Sanctions and third parties: Screening Base (100 names) and 5 dossiers per month. Services bought separately: $3,950/month. | $2,400 | $24,000 |
compliance | Compliance: Screening Base (100 names), Regulation 3 countries and 5 dossiers per month. Services bought separately: $5,450/month. | $3,900 | $39,000 |
growth | Market and growth: Sector, Tenders and Regulation 3 countries. Services bought separately: $4,400/month. | $3,400 | $34,000 |
complete | Complete: Screening Enterprise (10,000 names), Regulation 10 countries, Sector, Tenders and 10 dossiers per month. Services bought separately: $14,300/month. | $9,900 | $99,000 |
Errors
Errors use HTTP status codes and a JSON body:
{"error": {"code": "limit_exceeded", "message": "Your plan includes up to 1,000 names; you have 990.", "status": 403, "docs": "https://intel.unicornprivate.com/docs#errors"}}
| Status | Codes |
|---|---|
| 400 | invalid_json, invalid_parameter, invalid_entity, invalid_url |
| 401 | invalid_api_key |
| 402 | subscription_inactive, dossier_quota_exceeded |
| 403 | plan_upgrade_required, limit_exceeded |
| 404 | not_found |
| 413 | payload_too_large, too_many_entities |
| 429 | too_many_requests |
| 502, 503 | engine_error, module_unavailable (retry later; see /status) |
Screening
Names are compared every day with the lists shown on /status. Upsert by your own ref:
POST /v1/entities
{"entities": [{"ref": "SUP-0042", "name": "Example Trading LLC", "type": "company", "country": "AE", "aliases": ["Example Trading"]},
{"ref": "DIR-7", "name": "Jane Example", "type": "person", "dob": "1970-05"}]}
-> {"data": {"added": 2, "updated": 0, "total": 2}}
GET /v1/entities?q=&offset=&limit=, DELETE /v1/entities with {"refs": [...]}. Instant check without saving: POST /v1/screen (up to 100 names).
Matches: GET /v1/matches?status=open&since=2026-10-01T00:00:00Z. Each match has score (0 to 1), reasons, listName, sourceUrl and dates. A match is a possible match: verify it on the official source. Review: POST /v1/matches/{id}/review {"status": "cleared", "note": "Different date of birth"}. Audit log: GET /v1/audit or GET /v1/audit?format=csv.
Dossiers
POST /v1/dossiers {"name": "Example GmbH", "website": "example.de", "country": "DE", "language": "en"}
-> 201 {"data": {"id": "...", "status": "queued"}}
GET /v1/dossiers/{id} (status: queued, running, ready, failed)
GET /v1/dossiers/{id}.pdfA request uses one dossier of the month, then one purchased single dossier ($490 each, bought from the dashboard, also beyond the monthly quota); otherwise 402 dossier_quota_exceeded. A dossier_ready alert is sent when it is ready.
Monitoring: sector, regulation, tenders
The profile drives all three services. PUT /v1/profile:
{"languages": ["en"], "countries": ["EU", "US", "IT"], "sectors": ["payments"], "keywords": ["instant payments", "PSD3"],
"competitors": [{"name": "Example Pay", "website": "examplepay.com"}], "cpv": ["72000000"], "minValue": 100000,
"tenderProfiles": [{"name": "IT services", "keywords": ["software"], "cpv": ["72000000"], "countries": ["IT", "FR"]}]}
Feed: GET /v1/feed?module=regulation&since=...&limit=50. Items have title, summary in your language, sourceName, sourceUrl, publishedAt, relevance, and for tenders deadline, value, currency. Weekly briefing: GET /v1/briefings?module=tenders&week=2026-W44.
Webhooks
Up to 10 HTTPS endpoints (POST /v1/webhooks {"url": "...", "types": ["match", "tenders"]}; types: match, dossier_ready, news, sector, regulation, tenders; empty = all). Each alert is sent as a POST:
POST https://your.example/hook
Unicorn-Intel-Signature: t=1793000000,v1=<hex HMAC SHA-256 of "<t>.<raw body>" with your whsec_ secret>
Unicorn-Intel-Event-Id: evt_al_...
{"id": "evt_al_...", "type": "alert.match", "created": "2026-10-29T10:00:00.000Z",
"data": {"kind": "match", "refId": "...", "title": "...", "createdAt": "..."}}
Reply with 2xx within 10 seconds. Failed deliveries are retried after 1, 5, 30, 120, 360, 720 and 1440 minutes. Reject signatures older than 5 minutes. Test: POST /v1/webhooks/{id}/test.
// Node.js
const crypto = require('crypto');
function verify(secret, rawBody, header) {
const p = Object.fromEntries(header.split(',').map(x => x.split('=')));
if (Math.abs(Date.now() / 1000 - Number(p.t)) > 300) return false;
const mac = crypto.createHmac('sha256', secret).update(p.t + '.' + rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(p.v1));
}Examples
# Python
import requests
H = {"Authorization": "Bearer ui_live_..."}
r = requests.post("https://intel.unicornprivate.com/v1/screen", headers=H, json={"entities": [{"name": "Example Trading LLC"}]})
for m in r.json()["data"][0]["matches"]:
print(m["listName"], m["score"], m["sourceUrl"])
// JavaScript
const r = await fetch("https://intel.unicornprivate.com/v1/feed?module=tenders&limit=20", { headers: { Authorization: "Bearer ui_live_..." } });
const { data } = await r.json();