API usage and setup guide
Needine integrates with systems you already use. This guide explains how to activate API keys, authenticate requests, and issue your first certificate with verifiable traceability.
1. Prerequisites
- - Active Needine account.
- - Role with API key permissions (typically ADMIN).
- - An HTTP client environment (Postman, curl, or your backend).
- - API base URL for your deployment.
- - Rotated secret storage for API keys (Vault, AWS Secrets Manager, etc.).
Production defaults
- - Base URL:
https://api.needine.com - - Auth header:
X-API-Key: ndi_... - - Content type:
application/json
2. Quickstart in 6 steps
- 1Create an API key from Console > Administration > API Keys.
- 2Store the full key in your secrets manager (it is shown only once).
- 3Send the key in the X-API-Key header on every request.
- 4Register the AI model and vendor you use at /models and /vendors.
- 5Issue a certificate at /certificates with its evidences.
- 6Share the public verification link /verify/:id with third parties.
3. API key authentication
All machine-to-machine API calls must include the X-API-Key. Needine validates key prefix + SHA-256 hash and applies permissions from the key owner user.
Curl example
curl -X GET "https://your-api-domain/certificates?page=1&pageSize=20" \ -H "X-API-Key: ndi_xxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json"
Node.js fetch example
const res = await fetch("https://api.needine.com/certificates?page=1&pageSize=10", {
headers: {
"X-API-Key": process.env.NEEDINE_API_KEY,
"Content-Type": "application/json"
}
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();4. Recommended API flow
Step A
Register vendor
POST /vendors
Step B
Register model
POST /models
Step C
Issue certificate
POST /certificates
Step D
Get traceability
GET /certificates/:id/provenance
Step E
Public verification
GET /verification/:id
5. Minimum payload to issue a certificate
This sample uses fields validated by the current API contract. Adjust by your workflow and always validate in Swagger before go-live.
Valid certificateType values
ai_report | ai_audit | ai_model_card | ai_dataset_card | ai_evaluation | generic
{
"certificateType": "ai_report",
"reportName": "Quarterly AI Risk Summary",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Consulting",
"inputEvidence": [
{
"evidenceType": "input",
"sha256Hash": "b7c4f4...64hex",
"mimeType": "application/json",
"filename": "input.json",
"storageMode": "hash_only"
}
],
"outputEvidence": [
{
"evidenceType": "output",
"sha256Hash": "a99d2a...64hex",
"mimeType": "application/pdf",
"filename": "output.pdf",
"storageMode": "hash_only"
}
],
"model": {
"provider": "openai",
"modelName": "gpt-4o"
}
}6. End-to-end examples for backend teams
Use one of these snippets to issue and verify certificates from your integration layer.
curl (issue certificate)
curl -X POST "https://api.needine.com/certificates" \
-H "X-API-Key: ndi_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"certificateType": "ai_report",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Consulting",
"inputEvidence": [{"sha256Hash": "b7c4...", "evidenceType": "input"}],
"outputEvidence": [{"sha256Hash": "a99d...", "evidenceType": "output"}],
"model": {"provider": "openai", "modelName": "gpt-4o"}
}'JavaScript SDK
import { NeedineClient } from "@needine/sdk";
const client = new NeedineClient({ apiKey: process.env.NEEDINE_API_KEY });
const created = await client.createCertificate({
certificateType: "ai_report",
signerName: "Maria Lopez",
issuingCompany: "Acme Consulting",
inputEvidence: [{ sha256Hash: "b7c4...", evidenceType: "input" }],
outputEvidence: [{ sha256Hash: "a99d...", evidenceType: "output" }],
model: { provider: "openai", modelName: "gpt-4o" }
});
const verification = await client.verifyCertificate(created.certificateId);
console.log(created.certificateId, verification.valid, verification.trustLevel);Python SDK
from needine import NeedineClient
client = NeedineClient(api_key="ndi_xxx", base_url="https://api.needine.com")
created = client.create_certificate({
"certificateType": "ai_report",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Consulting",
"inputEvidence": [{"sha256Hash": "b7c4...", "evidenceType": "input"}],
"outputEvidence": [{"sha256Hash": "a99d...", "evidenceType": "output"}],
"model": {"provider": "openai", "modelName": "gpt-4o"}
})
verification = client.verify_certificate(created["certificateId"])
print(created["certificateId"], verification["valid"], verification["trustLevel"])7. Webhooks (optional)
Webhooks let your backend react in near real-time when certificate state changes. Register endpoint URLs from the Console (or API), subscribe to events, and process callbacks asynchronously in your integration layer.
Webhook management endpoints
- -
POST /webhooksregister endpoint (returns secret once). - -
GET /webhookslist endpoints + latest delivery info. - -
DELETE /webhooks/:idremove endpoint. - -
GET /webhooks/:id/deliveries?page=1&pageSize=20inspect delivery logs.
Supported event names
certificate.issued,certificate.revoked,anchor.confirmed,trust.updated
Current production triggers actively dispatch certificate lifecycle events: certificate.issued and certificate.revoked.
Delivery contract
- - Method: POST
- - Content-Type: application/json
- - Timeout per attempt: 10s
- - Retries: 3 attempts with backoff 1s, 4s, 9s
- - Success criteria: any HTTP 2xx response
- - Recommended receiver behavior: idempotent processing keyed by event + certificate ID.
Headers and body sent by Needine
POST https://your-system.example/webhooks/needine
Content-Type: application/json
X-Needine-Event: certificate.issued
X-Needine-Signature: sha256=<hex>
{
"event": "certificate.issued",
"payload": {
"certificateId": "cert_xxx",
"certificateType": "ai_report",
"status": "issued",
"issuedAt": "2026-03-18T19:48:08.800Z",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Consulting",
"verificationUrl": "https://needine.com/verify/cert_xxx"
},
"timestamp": "2026-03-18T19:48:09.120Z"
}Signature verification (Node.js)
import crypto from "crypto";
const rawSecret = process.env.NEEDINE_WEBHOOK_SECRET;
const signatureHeader = req.headers["x-needine-signature"]; // sha256=<hex>
const rawBody = requestRawBodyAsString;
const signingKey = crypto.createHash("sha256").update(rawSecret).digest("hex");
const expected = crypto.createHmac("sha256", signingKey).update(rawBody).digest("hex");
const received = String(signatureHeader || "").replace("sha256=", "");
if (!crypto.timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(received, "hex"))) {
throw new Error("Invalid webhook signature");
}Signature verification (Python)
import hashlib
import hmac
raw_secret = os.environ["NEEDINE_WEBHOOK_SECRET"]
signature_header = request.headers.get("X-Needine-Signature", "")
raw_body = request.get_data(as_text=True)
signing_key = hashlib.sha256(raw_secret.encode()).hexdigest()
expected = hmac.new(signing_key.encode(), raw_body.encode(), hashlib.sha256).hexdigest()
received = signature_header.replace("sha256=", "")
if not hmac.compare_digest(expected, received):
raise ValueError("Invalid webhook signature")8. AI vendors API
Track third-party AI vendors, their DPA status, certifications, and risk scores. Use these endpoints to maintain supply chain transparency as required by the EU AI Act.
Vendor management endpoints
- -
POST /vendorscreate a vendor (name, type, website, contactEmail). - -
GET /vendorslist vendors with optional filters (type, reviewStatus, dpaStatus). - -
PUT /vendors/:idupdate vendor info, DPA status, certifications, risk score. - -
DELETE /vendors/:idremove a vendor. - -
GET /vendors/:id/modelslist AI models linked to a specific vendor. - -
GET /vendors/exportexport vendor registry as CSV or JSON.
Vendor types
API_PROVIDER,PLATFORM,SELF_HOSTED,OPEN_SOURCE
DPA status workflow
NOT_REVIEWED →PENDING_SIGNATURE →SIGNED →EXPIRED
9. Model inventory and performance API
Extend model records with GPAI classification, inventory fields, and performance evaluations. Needine automatically detects metric drift between consecutive evaluations.
Model inventory endpoints
- -
PUT /models/:id/gpai-classificationset GPAI status and compute threshold. - -
PUT /models/:id/inventoryupdate use case, department, responsible person, risk level. - -
GET /models/inventory/exportexport full model registry as CSV or JSON.
Model performance endpoints
- -
POST /models/:modelId/performancerecord an evaluation (accuracy, precision, recall, F1, AUC). - -
GET /models/:modelId/performancelist evaluation history (paginated). - -
GET /models/:modelId/performance/latestget the most recent evaluation. - -
GET /models/:modelId/performance/driftcompare the latest two evaluations for metric drift.
Example: record a performance evaluation
curl -X POST "https://api.needine.com/models/model_xxx/performance" \
-H "X-API-Key: ndi_xxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"accuracy": 0.94,
"precision": 0.91,
"recall": 0.89,
"f1Score": 0.90,
"auc": 0.96,
"datasetName": "Q1-2026-validation",
"datasetSize": 12500,
"evaluatedBy": "data-science-team",
"notes": "Quarterly model evaluation"
}'10. EU AI Act compliance API
The compliance API covers each EU AI Act obligation with dedicated endpoints. All records are linked to certificates and models within your organization.
Transparency (Art. 13, 14, 50)
- -
POST /certificates/:id/transparencycreate a transparency record. - -
GET /certificates/:id/transparencyget the transparency record. - -
PUT /certificates/:id/transparencyupdate transparency info.
Fields: interactionType (CHATBOT, DEEPFAKE, EMOTION, BIOMETRIC, GENERATED_CONTENT), humanOversightType (HITL, HOTL, HIC), disclosure, override process, stop mechanism.
Technical Documentation (Art. 11, Annex IV)
- -
POST /certificates/:id/technical-doccreate technical documentation. - -
GET /certificates/:id/technical-docretrieve documentation. - -
PUT /certificates/:id/technical-docupdate documentation fields. - -
GET /certificates/:id/technical-doc/annex-ivget Annex IV compliance score.
Fields: system name, intended purpose, deployers, design specs, data governance, validation, performance metrics, risk mitigations.
FRIA — Fundamental Rights Impact Assessment (Art. 6, 27)
- -
POST /compliance/friacreate a FRIA. - -
GET /compliance/frialist all FRIAs. - -
PUT /compliance/fria/:idupdate FRIA details. - -
PATCH /compliance/fria/:id/reviewmark as reviewed.
Impact categories: privacy, non-discrimination, freedom, dignity, consumer protection. Status: DRAFT → COMPLETED → REVIEWED.
Risk Management, Monitoring, Literacy & Incidents
- -
POST/PUT /compliance/risk-managementmanage risks by phase (design → post-market). - -
POST/PUT /compliance/monitoring-planscreate post-market monitoring plans. - -
POST/GET /compliance/literacyrecord AI literacy training completions. - -
POST/PUT /compliance/incidentsreport compliance incidents. - -
POST/PUT /compliance/qmsquality management system records.
11. Blockchain anchoring API
Certificates are anchored on Arbitrum One via Merkle trees. Use these endpoints to trigger anchoring manually or verify an existing anchor on-chain.
Anchoring endpoints
- -
POST /anchors/triggertrigger blockchain anchoring for pending certificates. - -
GET /anchors/:id/verifyverify an anchor on-chain (returns Merkle root, tx hash, block number).
Anchor status: PENDING → SUBMITTED → CONFIRMED (or FAILED with automatic retries).
12. Reports and analytics API
Generate compliance and operational reports programmatically. All report endpoints accept optional date range query parameters.
Available report endpoints
- -
GET /reports/eu-ai-actrisk classification by certificate type. - -
GET /reports/eu-ai-act-fullfull compliance bundle (all modules combined). - -
GET /reports/compliance-scoreoverall compliance percentage. - -
GET /reports/fria-summaryFRIA count by status. - -
GET /reports/risk-management-summaryrisks by phase. - -
GET /reports/transparency-summarytransparency records count. - -
GET /reports/monitoring-summaryactive monitoring plans. - -
GET /reports/incidents-summaryincidents by status. - -
GET /reports/qms-summaryQMS documentation status. - -
GET /reports/literacy-summaryAI training completion percentage. - -
GET /reports/technical-doc-coveragetechnical documentation completeness. - -
GET /reports/model-performancemodel performance stats. - -
GET /reports/gdpr-trailGDPR audit trail. - -
GET /reports/declarationexport compliance declaration.
13. Common errors and fixes
401 Unauthorized
Cause: API key missing, revoked, or expired.
Fix: Check the X-API-Key header and key status in Console.
403 Forbidden
Cause: The API key does not have scope for this action.
Fix: Create a key with the correct scopes or adjust owner permissions.
404 Not Found
Cause: Invalid certificate ID or out-of-organization resource.
Fix: Confirm you are using the exact certificateId returned at issuance.
429 Too Many Requests
Cause: Too many requests in a short interval.
Fix: Apply retries with exponential backoff and retry queues.
How to integrate Needine based on the customer's IT infrastructure
Needine plugs into the customer's existing systems: it does not require replacing the ERP, CRM, document platform, or AI pipeline. Identify your scenario in the table and follow the recommended pattern below.
| Customer type | How they call Needine | Go to pattern |
|---|---|---|
| Modern customer with their own backend | Direct REST API or SDK | Pattern A |
| Customer with Java / .NET / Python / Node stack | SDK or HTTP client | Pattern B |
| Customer with manual or low-code processes | Middleware / connector | Pattern C |
| Customer with ERP / CRM | Adapter between ERP and Needine | Pattern D |
| Customer with closed infrastructure | Private integration, VPN, allowlist or dedicated deployment | Pattern E |
| Customer without enough technical capacity | Assisted integration service | Pattern F |
certificateId stored?Pattern A — Modern customer with their own backend
Direct call to the REST API or use of the official SDK. This is the fastest pattern (1-3 days): event generated → local hash of evidence → POST to Needine → store certificateId → subscribe to webhooks.
Flow diagram
[Customer backend] │ 1. Generates AI output │ 2. sha256(input) + sha256(output) │ 3. POST /certificates (X-API-Key) ▼ [Needine API] -- 4. Returns certificateId, verificationUrl, trustLevel │ │ 5. anchor.confirmed (HMAC-signed webhook) ▼ [Customer backend] stores certificateId in its DB / ERP / CRM
Node / TypeScript SDK
import { NeedineClient } from "@needine/sdk";
import crypto from "crypto";
const client = new NeedineClient({ apiKey: process.env.NEEDINE_API_KEY! });
const sha256 = (buf: Buffer) => crypto.createHash("sha256").update(buf).digest("hex");
const cert = await client.createCertificate({
certificateType: "ai_report",
signerName: "Maria Lopez",
issuingCompany: "Acme SaaS",
inputEvidence: [{ sha256Hash: sha256(inputBuffer), evidenceType: "input" }],
outputEvidence: [{ sha256Hash: sha256(outputBuffer), evidenceType: "output" }],
model: { provider: "openai", modelName: "gpt-4o" },
});
await db.certificates.update({ where: { jobId }, data: { needineId: cert.certificateId } });Python SDK
from needine import NeedineClient
import hashlib, os
client = NeedineClient(api_key=os.environ["NEEDINE_API_KEY"])
def sha256(b: bytes) -> str:
return hashlib.sha256(b).hexdigest()
cert = client.create_certificate({
"certificateType": "ai_report",
"signerName": "Maria Lopez",
"issuingCompany": "Acme SaaS",
"inputEvidence": [{"sha256Hash": sha256(input_bytes), "evidenceType": "input"}],
"outputEvidence": [{"sha256Hash": sha256(output_bytes), "evidenceType": "output"}],
"model": {"provider": "openai", "modelName": "gpt-4o"},
})
print(cert["certificateId"], cert.get("verificationUrl"))Pattern B — Languages without an official SDK (Java, .NET, Go, PHP, Ruby)
While we publish native SDKs, any standard HTTP client works. The API is REST + JSON, with OpenAPI available at /api/docs, which lets you generate clients automatically with openapi-generator.
Java 17+ (HttpClient)
import java.net.http.*;
import java.net.URI;
var body = """
{
"certificateType": "ai_report",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Industrial",
"inputEvidence": [{"sha256Hash":"%s","evidenceType":"input"}],
"outputEvidence": [{"sha256Hash":"%s","evidenceType":"output"}],
"model": {"provider":"openai","modelName":"gpt-4o"}
}
""".formatted(inputHash, outputHash);
var req = HttpRequest.newBuilder(URI.create("https://api.needine.com/certificates"))
.header("X-API-Key", System.getenv("NEEDINE_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
var res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());.NET 8 (HttpClient)
using System.Net.Http.Json;
var http = new HttpClient { BaseAddress = new Uri("https://api.needine.com/") };
http.DefaultRequestHeaders.Add("X-API-Key", Environment.GetEnvironmentVariable("NEEDINE_API_KEY"));
var payload = new {
certificateType = "ai_report",
signerName = "Maria Lopez",
issuingCompany = "Acme Bank",
inputEvidence = new[] { new { sha256Hash = inputHash, evidenceType = "input" } },
outputEvidence = new[] { new { sha256Hash = outputHash, evidenceType = "output" } },
model = new { provider = "openai", modelName = "gpt-4o" }
};
var res = await http.PostAsJsonAsync("certificates", payload);
res.EnsureSuccessStatusCode();
var cert = await res.Content.ReadFromJsonAsync<Dictionary<string, object>>();Go
payload := map[string]any{
"certificateType": "ai_report",
"signerName": "Maria Lopez",
"issuingCompany": "Acme Logistics",
"inputEvidence": []map[string]string{{"sha256Hash": inputHash, "evidenceType": "input"}},
"outputEvidence": []map[string]string{{"sha256Hash": outputHash, "evidenceType": "output"}},
"model": map[string]string{"provider": "openai", "modelName": "gpt-4o"},
}
b, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.needine.com/certificates", bytes.NewReader(b))
req.Header.Set("X-API-Key", os.Getenv("NEEDINE_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)PHP 8
$payload = [
"certificateType" => "ai_report",
"signerName" => "Maria Lopez",
"issuingCompany" => "Acme Legal",
"inputEvidence" => [["sha256Hash" => $inputHash, "evidenceType" => "input"]],
"outputEvidence" => [["sha256Hash" => $outputHash, "evidenceType" => "output"]],
"model" => ["provider" => "openai", "modelName" => "gpt-4o"],
];
$ch = curl_init("https://api.needine.com/certificates");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("NEEDINE_API_KEY"), "Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$cert = json_decode(curl_exec($ch), true);openapi-generator-cli generate -i https://api.needine.com/api/docs-json \ -g java -o ./needine-java # csharp-netcore, go, php, ruby, rust, kotlin, typescript-axios
Pattern C — Manual or low-code processes (Make, Zapier, n8n, Power Automate)
For customers without a development team, any automation platform can call Needine as a generic HTTP module. The customer only configures the URL, the API key, and the JSON.
Make / Zapier
- • Trigger: new file in Drive / Dropbox / SharePoint.
- • Step: HTTP module → POST
/certificates. - • Header:
X-API-Key. - • Output:
certificateId,verificationUrl. - • Action: append URL to file or send by email.
n8n (self-hosted)
- • Crypto node → SHA-256 of the file.
- • HTTP Request node → POST to Needine.
- • Webhook node → receive
certificate.issued. - • Set node → update your database / Notion / Airtable.
Microsoft Power Automate
- • Trigger: When a file is created (SharePoint).
- • Compute hash with
sha256(...)function. - • HTTP action to
/certificates. - • Update file metadata with
certificateId.
Google Apps Script
- • Trigger: onFormSubmit / onFileCreate.
- •
UrlFetchApp.fetch()with headers. - • Save response in Sheets / Drive.
Power Automate example (HTTP action)
Method: POST
URI: https://api.needine.com/certificates
Headers: X-API-Key : @{parameters('needine_api_key')}
Content-Type: application/json
Body:
{
"certificateType": "ai_report",
"signerName": "@{triggerBody()?['Editor']?['DisplayName']}",
"issuingCompany": "@{parameters('company')}",
"inputEvidence": [{"sha256Hash": "@{outputs('Hash_input')}", "evidenceType": "input"}],
"outputEvidence": [{"sha256Hash": "@{outputs('Hash_output')}", "evidenceType": "output"}],
"model": { "provider": "openai", "modelName": "gpt-4o" }
}Pattern D — Customer with ERP / CRM (SAP, Salesforce, Dynamics, ServiceNow, Odoo)
The ERP core is not modified. A lightweight adapter (microservice or serverless function) is introduced to listen to the ERP event, normalize the payload, compute hashes, call Needine, and return the certificateId to the ERP to be saved in a custom field.
Adapter architecture
[ERP / CRM] │ Event (BAPI / Outbound Message / Business Rule / Webhook) ▼ [Needine adapter] ← customer or Needine microservice │ • ERP fields → Needine schema mapping │ • SHA-256 computation │ • Retries + queue (idempotency by externalId) │ • Vault for API key ▼ [Needine API] │ │ signed webhook ▼ [Adapter] → Update ERP record (custom field: needine_certificate_id)
SAP S/4HANA
- • SAP CPI / PI/PO with REST iflow.
- • OData Service exposes event → CPI calls Needine.
- • Custom field
ZNEEDINE_CERTIDin the master table.
Salesforce
- • Apex callout with
Named Credential(manages API key). - • Trigger after insert/update → async call (
@futureor Queueable). - • Platform Event to receive Needine webhooks.
Microsoft Dynamics 365
- • Power Automate flow (cloud) or C# plugin (sandbox).
- • Azure Function as adapter, invoked by Dataverse webhook.
ServiceNow
- • Business Rule + REST Message v2.
- • Custom IntegrationHub Spoke.
- • Inbound REST to receive webhooks.
Odoo
- • Custom Python module using
needine-sdk. - • Hook on
create()oraction_done().
Document management
- • SharePoint / M-Files / Alfresco / DocuWare.
- • Hook on file checkin → certify and save URL.
Apex (Salesforce) — example
public with sharing class NeedineService {
@future(callout=true)
public static void certify(Id reportId) {
Report__c r = [SELECT Id, OutputHash__c, InputHash__c FROM Report__c WHERE Id = :reportId];
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Needine/certificates');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serialize(new Map<String, Object>{
'certificateType' => 'ai_report',
'signerName' => UserInfo.getName(),
'issuingCompany' => 'Acme',
'inputEvidence' => new List<Object>{ new Map<String,String>{ 'sha256Hash' => r.InputHash__c, 'evidenceType' => 'input' } },
'outputEvidence' => new List<Object>{ new Map<String,String>{ 'sha256Hash' => r.OutputHash__c, 'evidenceType' => 'output' } },
'model' => new Map<String,String>{ 'provider' => 'openai', 'modelName' => 'gpt-4o' }
}));
HttpResponse res = new Http().send(req);
Map<String,Object> body = (Map<String,Object>) JSON.deserializeUntyped(res.getBody());
update new Report__c(Id = reportId, NeedineCertificateId__c = (String) body.get('certificateId'));
}
}Pattern E — Closed infrastructure (banking, healthcare, defense, public sector)
When the customer has strong network restrictions, data residency, or compliance requirements, additional mechanisms apply:
IP allowlist / firewall
Needine publishes a stable outbound IP range. The customer adds it to their firewall to allow inbound webhooks and API responses.
Site-to-site VPN / private link
IPsec tunnel or AWS PrivateLink / Azure Private Endpoint so traffic never goes over the public Internet.
Corporate proxy with MITM
The SDK accepts a custom baseUrl and CA bundle. Recommended: pin the Needine fingerprint and bypass the proxy for webhooks (already validated with HMAC).
mTLS
Available on demand. Each side presents an X.509 certificate; useful for regulated sectors that do not accept API keys as the sole factor.
Dedicated / on-premise deployment
Official Docker images of the Needine backend + trust engine + customer Postgres. Optional blockchain anchoring. 100% residency in customer infrastructure.
No inbound webhooks (polling mode)
If the customer's network does not accept callbacks, their system polls every N minutes: GET /certificates?updatedAfter=….
Sensitive data (GDPR / secrets)
The raw payload never leaves the customer: only SHA-256 hashes and metadata are sent. Compatible with the right to erasure (PII off-chain, hash on-chain).
Corporate SSO (Azure AD, Okta, Keycloak)
Bidirectional OAuth2 / OIDC integration. Roadmap: SAML 2.0 for legacy customers.
On-premise deployment (minimal docker-compose)
services:
needine-api:
image: registry.needine.com/needine-api:stable
env_file: .env.needine
depends_on: [postgres]
ports: ["8080:3000"]
trust-engine:
image: registry.needine.com/trust-engine:stable
env_file: .env.needine
postgres:
image: postgres:16
environment:
POSTGRES_DB: needine
POSTGRES_USER: needine
POSTGRES_PASSWORD_FILE: /run/secrets/db
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: {} }Polling (when no webhooks are available)
curl -G "https://api.needine.com/certificates" \ -H "X-API-Key: $NEEDINE_API_KEY" \ --data-urlencode "updatedAfter=$(cat .needine_cursor)" \ --data-urlencode "pageSize=100"
Pattern F — Customer without technical capacity (assisted integration service)
If the customer has no development team, Needine delivers a turn-key solution that requires no programming:
- **Needine web portal**: the user uploads the file, the system computes the hash in the browser and issues the certificate without any coding.
- **Pre-configured connector** delivered by Needine or a partner: a Docker image or an n8n app with ready-made flows; the customer only enters their API key.
- **Make / Zapier / Power Automate templates** published: import and connect.
- **Email-to-certify**: send the evidence as an attachment to a dedicated address and receive the certificate by email.
- **Managed service**: Needine or a partner integrator runs the solution for the customer (assisted Enterprise package).
Three commercial integration tiers
| Tier | Time | Customer profile |
|---|---|---|
| QuickStart API | 1-3 days | Modern backend, 1 generalist developer (Pattern A/B) |
| Assisted connector | 1-3 weeks | ERP/CRM, low-code (Pattern C/D) |
| Enterprise | 4-12 weeks | Restricted infra, on-prem, complex SSO (Pattern E/F) |
Computing SHA-256 locally (evidence never leaves)
Needine receives the hash, not the content. Compute SHA-256 inside the customer's network and send only the lowercase hexadecimal digest (64 characters).
# bash
sha256sum file.pdf | awk '{print $1}'# PowerShell (Get-FileHash file.pdf -Algorithm SHA256).Hash.ToLower()
// Node
crypto.createHash("sha256").update(buf).digest("hex");# Python hashlib.sha256(data).hexdigest()
// Java
MessageDigest.getInstance("SHA-256").digest(bytes); // -> bytesToHex// C# Convert.ToHexString(SHA256.HashData(bytes)).ToLowerInvariant();
// Browser (no upload required)
const buf = await file.arrayBuffer();
const h = await crypto.subtle.digest("SHA-256", buf);
[...new Uint8Array(h)].map(b => b.toString(16).padStart(2,"0")).join("");// Go sum := sha256.Sum256(data) hex.EncodeToString(sum[:])
Integration best practices
Idempotency
Send the Idempotency-Key: <your-event-uuid> header. If you retry, no duplicate certificates will be created.
Retries with backoff
Retry only 429, 502, 503, 504, and network errors. Exponential backoff 1s, 2s, 4s, 8s (max. 5 attempts).
Rate limiting
Respect X-RateLimit-Remaining and Retry-After headers. Configure a client-side semaphore.
Pagination
?page=N&pageSize=20 (max 100). The response includes total, page, pageSize.
API key storage
Vault / Azure Key Vault / AWS Secrets Manager / GCP Secret Manager. Never in repo or frontend.
Rotation
API keys: quarterly rotation. OAuth: POST /oauth/clients/:id/rotate-secret. Webhooks: regenerate the secret when security requests it.
Observability
Log the X-Request-Id returned by the API; it eases support. Health endpoint: /health.
Webhook validation
Verify HMAC before processing. Return 2xx in under 5s; any heavy logic goes to a queue.
Sandbox, OpenAPI, and public verification
- **Sandbox**:
https://sandbox.api.needine.com— issues test certificates, free, with no real blockchain anchoring. - **Swagger / OpenAPI**:
/api/docsand JSON at/api/docs-jsonto generate clients. - **Postman collection**: downloadable from the developer portal.
- **Public verification without auth**:
GET /verification/{certificateId}— useful for auditors or third parties. - **Audit rooms**: temporary tokens (
POST /audit-rooms) that grant read-only access to an auditor for X hours.
Integration checklist (before going to production)
- ✓Identified the business event that triggers certification
- ✓API key created and stored in the customer's vault
- ✓SHA-256 hash computed locally; raw content never leaves the customer
- ✓Source-system field mapping to the Needine schema documented
- ✓certificateId persisted in the source system (field or table)
- ✓Webhooks configured with verified HMAC, or active polling if no inbound callback
- ✓Idempotency-Key implemented on every POST /certificates
- ✓Retries with exponential backoff only on 429/5xx
- ✓Logs include X-Request-Id for support
- ✓Sandbox validated with at least 10 test certificates before switching to production
- ✓Rate limit measured and sized to the actual expected volume
- ✓API key and webhook secret rotation plan
- ✓Public verification tested by an external auditor
- ✓DPA / contracts signed if personal data is involved
Want us to help you integrate?
Book a 60-90 minute Integration Assessment with our technical team. We leave with the chosen pattern, the adapter defined, and a deployment plan.