ESGNode | Developer API
Product docs Get a key →

ESGNode Developer API

Run ESGNode's three core features programmatically: Analysis (requirement-by-requirement compliance scoring), Compare (multi-document cross-comparison), and Report Write (AI report generation). Authenticate with an API key; pay per call from a prepaid credit wallet — no per-request checkout.

Base URL: https://esgnode.com/api/v1/  ·  All responses are JSON. All work is asynchronous: POST starts a job, GET polls for results.

Authentication

Create a key in Settings → Developer API (Professional plan or higher). The raw key is shown once — store it securely. Send it on every request:

Authorization: Bearer esgx_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are scoped to one or more permissions: analysis, compare, report. A key without the matching permission gets 403 INSUFFICIENT_PERMISSIONS.

Test keys. Keys minted in a sandbox environment (esgx_test_…) run for free and never charge the wallet — use them to integrate before going live.

Credits & pricing

Credits are denominated in US dollars. Buy a bundle in the dashboard; the balance is debited per call. Credits never expire.

BundlePriceCreditsEffective rate
Starter$25$251.00
Growth$85$1000.85
Scale$320$4000.80
Enterprise$1,125$1,5000.75

Per-call cost

FeatureFormulaMinimum
Analysis$3 base + $0.04/page (max 600) + $1.50/standard + $1 AI drafts + $0.50 vision$5.00
Compare$1.50/document + $2.00/standard$4.00
Report write$6 base + $0.25/requirement$10.00

The exact charge is returned as credits_charged_cents in every POST response. A fully-failed job is automatically refunded.

Typical flow

# 1. Upload a PDF → get report_id
curl -s https://esgnode.com/api/v1/upload.php \
  -H "Authorization: Bearer $ESGX_KEY" \
  -F "file=@sustainability-report.pdf"

# 2. Start an analysis against a standard
curl -s https://esgnode.com/api/v1/analysis.php \
  -H "Authorization: Bearer $ESGX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"report_id":123,"standard_id":7,"ai_drafts":true}'

# 3. Poll until status == "done"
curl -s "https://esgnode.com/api/v1/analysis.php?id=456" \
  -H "Authorization: Bearer $ESGX_KEY"

Upload

POST /api/v1/upload.php — permission: analysis or compare. Multipart field file (PDF, up to 100 MB). Free; charge happens at analyze/compare.

{ "error": false, "report_id": 123, "filename": "report.pdf", "page_count": 148 }

Analysis

POST /api/v1/analysis.php — permission: analysis.

{ "report_id": 123, "standard_id": 7, "ai_drafts": true, "vision": false }

Response:

{ "error": false, "analysis_id": 456, "status": "pending",
  "credits_charged_cents": 1150, "credits_remaining_cents": 8850 }

GET /api/v1/analysis.php?id=456 — poll. When status is done:

{ "error": false, "analysis_id": 456, "status": "done", "score": 0.74,
  "standard": { "id": 7, "name": "GRI Universal Standards" },
  "results": [
    { "requirement_id": 12, "code": "GRI 2-1", "title": "Organizational details",
      "status": "found", "confidence": 0.91,
      "matched_text": "…verbatim quote…", "page": 4, "ai_draft": null }
  ] }

DELETE /api/v1/analysis.php?id=456 — delete an analysis.

Compare

POST /api/v1/compare.php — permission: compare. Omit standard_id for wildcard (topic-discovery) mode. 2–5 documents.

{ "report_ids": [123, 124, 125], "standard_id": 7 }

GET /api/v1/compare.php?id=789 returns results[] with per-criterion findings when done.

Report write

POST /api/v1/report.php — permission: report. The project must already exist (create it in the dashboard).

{ "project_id": 55 }

GET /api/v1/report.php?id=55 returns status, generation_step, has_output.

Standards

GET /api/v1/standards.php — list available frameworks with requirement counts.

{ "error": false, "standards": [
  { "id": 7, "name": "GRI Universal Standards", "code": "GRI1", "requirement_count": 142 }
] }

Credits endpoint

GET /api/v1/credits.php — current balance + last 20 ledger entries. Works with an API key or a dashboard session.

{ "error": false, "balance_cents": 8850, "balance_usd": 88.5,
  "transactions": [ { "delta_cents": -1150, "reason": "analysis",
    "reference_id": "report:123", "balance_after": 8850, "created_at": "…" } ] }

Rate limits

TierPer minutePer dayConcurrent jobs
Default102003
Growth ($100+ lifetime)301,00010
Scale ($400+ lifetime)1005,00025

Exceeding a limit returns 429 RATE_LIMITED with a Retry-After header.

Errors

All errors share one envelope:

{ "error": true, "code": "INSUFFICIENT_CREDITS",
  "message": "Your balance ($0.45) is below the cost of this analysis ($5.00). Top up at /settings?tab=api.",
  "balance_cents": 45, "required_cents": 500 }
CodeHTTPMeaning
INVALID_API_KEY401Missing or malformed key
KEY_REVOKED401Key revoked or expired
INSUFFICIENT_PERMISSIONS403Key lacks the feature permission
INSUFFICIENT_CREDITS402Wallet balance too low
RATE_LIMITED429Too many requests
REPORT_NOT_FOUND / ANALYSIS_NOT_FOUND404Resource missing or not yours
VALIDATION_ERROR422Bad request body
SERVER_ERROR500Unexpected failure