API Help Guide

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

  1. 1Create an API key from Console > Administration > API Keys.
  2. 2Store the full key in your secrets manager (it is shown only once).
  3. 3Send the key in the X-API-Key header on every request.
  4. 4Create or register the AI model you use at /models.
  5. 5Issue a certificate at /certificates with its evidences.
  6. 6Share the public verification link /verify/:id with third parties.

3. API key authentication

All machine-to-machine API calls must include theX-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 model

POST /models

Step B

Issue certificate

POST /certificates

Step C

Get traceability

GET /certificates/:id/provenance

Step D

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 /webhooks register endpoint (returns secret once).
  • - GET /webhooks list endpoints + latest delivery info.
  • - DELETE /webhooks/:id remove endpoint.
  • - GET /webhooks/:id/deliveries?page=1&pageSize=20 inspect delivery logs.

Supported event names

certificate.issued,certificate.revoked,anchor.confirmed,trust.updated

Current production triggers actively dispatch certificate lifecycle events:certificate.issuedandcertificate.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";

// Store and protect the raw secret returned once at webhook creation (whsec_...)
const rawSecret = process.env.NEEDINE_WEBHOOK_SECRET;
const signatureHeader = req.headers["x-needine-signature"]; // sha256=<hex>
const rawBody = requestRawBodyAsString; // do not reserialize JSON

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)  # exact raw body

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. 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.