API Reference

Integration guides

Webhook signature verification, upload-and-poll examples, and API key management guidance.

Webhook signatures

Every delivery includes headers for verifying authenticity. Compute an HMAC-SHA256 hex digest of <timestamp>.<raw JSON body> using the webhook signing secret, then compare it to X-NiceData-Signature.

Header Description
X-NiceData-Event Event type.
X-NiceData-Timestamp Unix timestamp used in the signed payload.
X-NiceData-Signature HMAC-SHA256 hex digest.
Delivery behavior

NiceData treats HTTP 2xx responses as successful. Failed deliveries are retried up to 3 times after the first attempt: 30 seconds, 2 minutes, then 10 minutes.

Node.js
const crypto = require("crypto");

function verifyWebhook(rawBody, timestamp, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const signatureBuffer = Buffer.from(signature || "", "hex");
  const expectedBuffer = Buffer.from(expected, "hex");
  if (signatureBuffer.length !== expectedBuffer.length) return false;

  return crypto.timingSafeEqual(signatureBuffer, expectedBuffer);
}
Python
import hashlib
import hmac

def verify_webhook(raw_body, timestamp, signature, secret):
    payload = timestamp.encode() + b"." + raw_body
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Examples

Use polling when you want a simple synchronous workflow, or webhooks when your application can receive asynchronous callbacks.

Upload and poll
# 1. Upload a document
RESPONSE=$(curl -s -X POST \
  -H "Authorization: Bearer nd_live_abc123..." \
  -F "[email protected]" \
  https://api.nicedata.ai/v1/projects/{project_id}/documents)
DOC_ID=$(echo "$RESPONSE" | jq -r '.document.id')

# 2. Poll until processing finishes
while true; do
  STATUS=$(curl -s -H "Authorization: Bearer nd_live_abc123..." \
    https://api.nicedata.ai/v1/projects/{project_id}/documents/$DOC_ID | jq -r '.document.status')
  [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
  sleep 5
done

# 3. Read extracted data
curl -s -H "Authorization: Bearer nd_live_abc123..." \
  https://api.nicedata.ai/v1/projects/{project_id}/documents/$DOC_ID | jq '.document.parsed_data'
Batch upload
for file in /path/to/docs/*.pdf; do
  curl -s -X POST \
    -H "Authorization: Bearer nd_live_abc123..." \
    -F "file=@$file" \
    https://api.nicedata.ai/v1/projects/{project_id}/documents \
    | jq '{id: .document.id, filename: .document.filename}'
done

API key management

API keys are managed from Settings > API. Create a key with a descriptive name, use it for one integration, and revoke it when you no longer need it.

  • Create a key with a descriptive name, then copy the token immediately. The full token is shown only once.
  • Keys are prefixed with nd_live_ and do not expire automatically.
  • Each key has full public API access for its organization. Create one key per integration for clean rotation.
  • Revoking a key disables it immediately and future requests return 401.