API Reference

All endpoints require an API key via the X-API-Key header. Base URL: https://app.nodium.io/api/v1

Authentication

Include your API key in every request:

X-API-Key: ndm_your_api_key_here

Keys are scoped to an organization. Generate them in Dashboard → API Keys.

Error codes

StatusErrorMeaning
401Missing X-API-Key headerNo API key provided
401Invalid API keyKey not found or revoked
400Validation failedRequest body doesn't match schema
403PLAN_LIMITElement or heal limit reached
404Element not foundElement ID doesn't exist in your org
422HEAL_FAILEDNo matching element found in HTML

Heal

All Heal endpoints live under /api/v1/heal/.

Elements

GET/api/v1/heal/elements

List all tracked elements in your organization.

Query parameters

  • project — Filter by project name (optional)
  • url — Filter by page URL (optional)
Response
[
  {
    "id": "uuid",
    "name": "Add to cart button",
    "selector": "#add-to-cart",
    "url": "https://example.com/product",
    "project": "my-store",
    "createdAt": "2024-01-01T00:00:00Z"
  }
]
POST/api/v1/heal/elements

Register a new element to track.

Request body
{
  "name": "string (required)",
  "project": "string (required)",
  "url": "string URL (required)",
  "selector": "string CSS selector (required)",
  "domContext": {
    "target": {
      "tag": "button",
      "id": "add-to-cart",
      "classes": ["btn"],
      "attributes": {},
      "textContent": "Add to cart"
    },
    "parents": [],
    "selector": "#add-to-cart",
    "selectors": [
      { "type": "byId", "selector": "#add-to-cart", "verified": true }
    ],
    "url": "https://example.com",
    "timestamp": 1709000000
  },
  "screenshot": "data:image/png;base64,... (optional)"
}
Response (201)
{
  "id": "uuid",
  "name": "Add to cart button",
  "createdAt": "2024-01-01T00:00:00Z"
}
GET/api/v1/heal/elements/:id

Get a single element with full details including DOM context.

Response
{
  "id": "uuid",
  "name": "Add to cart button",
  "selector": "#add-to-cart",
  "url": "https://example.com/product",
  "project": "my-store",
  "domContext": { ... },
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}
DELETE/api/v1/heal/elements/:id

Delete a tracked element.

Response
{ "success": true }
GET/api/v1/heal/elements/:id/history

Get healing history for an element.

Response
[
  {
    "id": "uuid",
    "oldSelector": ".old-class",
    "newSelector": "#new-id",
    "method": "cascade",
    "confidence": 0.97,
    "status": "success",
    "latencyMs": 3,
    "createdAt": "2024-01-15T12:00:00Z"
  }
]

Check

POST/api/v1/heal/check

Validate a selector against current HTML. Optionally auto-heal if broken.

Request body
{
  "elementId": "uuid (required)",
  "currentHtml": "string — full page HTML (required, max 512KB)",
  "autoHeal": false
}
Response — selector valid
{
  "valid": true,
  "selector": "#add-to-cart"
}
Response — broken, healed
{
  "valid": false,
  "selector": "#add-to-cart",
  "healed": true,
  "newSelector": "[data-testid='cart-btn']",
  "confidence": 0.92,
  "method": "cascade"
}
Response — broken, not healed
{
  "valid": false,
  "selector": "#add-to-cart",
  "healed": false
}

Heal

POST/api/v1/heal

Heal a broken selector. Runs the 3-tier healing engine (cascade → heuristic → vision).

Request body
{
  "elementId": "uuid (required)",
  "currentHtml": "string — full page HTML (required, max 512KB)"
}
Response — success
{
  "success": true,
  "newSelector": "#checkout-btn",
  "confidence": 0.97,
  "method": "cascade",
  "latencyMs": 3
}
Response — failed (422)
{
  "success": false,
  "error": "HEAL_FAILED",
  "message": "Could not find a matching element in the provided HTML"
}
POST/api/v1/heal/batch

Heal up to 50 elements in a single call. Results are returned per element.

Request body
{
  "elementIds": ["uuid1", "uuid2", "uuid3"],
  "currentHtml": "string — full page HTML (required, max 512KB)"
}
Response
{
  "results": [
    {
      "elementId": "uuid1",
      "success": true,
      "newSelector": "#btn-1",
      "confidence": 0.97,
      "method": "cascade"
    },
    {
      "elementId": "uuid2",
      "success": false,
      "error": "HEAL_FAILED"
    },
    {
      "elementId": "uuid3",
      "success": false,
      "error": "PLAN_LIMIT"
    }
  ]
}

Status

GET/api/v1/status

Health check endpoint. No authentication required.

Response
{ "status": "ok" }

Webhooks

Configure webhooks in the Dashboard to receive real-time notifications. Payloads are signed with HMAC-SHA256 using your webhook secret.

Events

  • heal.success — A selector was successfully healed
  • heal.failed — A heal attempt failed

Headers

  • X-Nodium-Signature — HMAC-SHA256 hex digest of the body
  • X-Nodium-Event — Event name
  • Content-Type: application/json
Webhook payload
{
  "event": "heal.success",
  "timestamp": "2024-01-15T12:00:00Z",
  "data": {
    "elementId": "uuid",
    "oldSelector": ".old-class",
    "newSelector": "#new-id",
    "method": "cascade",
    "confidence": 0.97
  }
}

Verify signature (Node.js)

const crypto = require('crypto');

function verify(body, secret, signature) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return expected === signature;
}