Public API docs

Create projects, track setup, and receive signed updates from BacklinkJet.

This is the public API reference for automation keys, project creation, setup status, webhooks, errors, limits, and a live request playground.

Create one automation key

Open Integrations in the dashboard and create an automation key. Choose Start projects and watch progress when another tool should create projects and check status.

Send each new project

When a new project, client, or site arrives in another tool, POST the domain to BacklinkJet. Existing domains are reused instead of duplicated.

Follow progress automatically

Poll the status endpoint or add webhooks so your tool knows when setup progress, next actions, and site checks change. Show setup.progress.label and setup.progress.description when a no-code tool asks what to display.

No-code recipes

Start with the tool your team already has.

These paths avoid custom code. Use the snippets below only when your tool asks for a request body, endpoint, or webhook signature check.

1

Zapier: catch new requests

Use Webhooks by Zapier with Catch Hook, then add a POST request to BacklinkJet with the site URL and your API key.

2

Make: HTTP module

Use the HTTP module to POST a project, then add another HTTP step to read status or let a webhook trigger the scenario.

3

Client portal or internal dashboard

Import the OpenAPI file into Retool, a client portal, or an internal dashboard so non-technical users can start projects from a form.

Authentication

Authentication

Send every request with an automation key in the Authorization: Bearer header. Keys are shown once when created, so copy the value into your automation tool before closing the dialog.

Create and revoke keys from Connected tools in the dashboard.
Use separate keys for production automations, test automations, and client portals.
Regenerate a key if it has been pasted into logs, shared documents, or a browser screenshot.
Permissions

API key permissions

Pick the narrowest key that lets the external tool complete its job. Permission names are what users see in the dashboard.

Watch progress only

Read project lists and project setup status without letting the external tool create new projects.

projects:read

Use for

Client portals, dashboards, status widgets, and reporting tools.

Start projects and watch progress

Create or reuse projects from an external workflow, then read status for the same workspace.

projects:readprojects:write

Use for

Zapier, Make, n8n, signup forms, sales handoffs, and internal intake tools.

Endpoint reference

Endpoint reference

All endpoints use the same base URL and bearer key. Responses are JSON and errors use the same error envelope.

GET/projects

List projects

Watch progress only

Returns the projects visible to the automation key so an external dashboard or portal can let a user choose which BacklinkJet project to inspect.

Request body

None.

Results are workspace-scoped by the key.

Use this endpoint before calling a status endpoint from a client portal.

Success response

{
  "data": [
    {
      "id": "proj_123",
      "name": "Example",
      "primaryDomain": "https://example.com",
      "registeredDomain": "example.com",
      "createdAt": "2026-05-18T10:30:00.000Z"
    }
  ]
}

Error responses

401Missing, revoked, or malformed automation key.
403The key cannot read projects in this workspace.
429Too many requests; wait for the Retry-After window.
POST/projects

Create a project

Start projects and watch progress

Creates a project for a submitted domain or returns the existing matching project, then starts the first setup scan when needed.

Request body

{
  "domain": "https://example.com",
  "name": "Example"
}

The domain is normalized before duplicate checks.

A 200 response means BacklinkJet reused an existing project; a 201 response means it created a new one.

Success response

{
  "project": {
    "id": "proj_123",
    "name": "Example",
    "primaryDomain": "https://example.com",
    "registeredDomain": "example.com",
    "createdAt": "2026-05-18T10:30:00.000Z"
  },
  "existing": false,
  "onboarding": {
    "scanRunId": "scan_456"
  },
  "links": {
    "status": "/api/v1/projects/proj_123/status",
    "dashboard": "/projects/proj_123/actions"
  }
}

Error responses

400The request body is missing a valid domain.
401Missing, revoked, or malformed automation key.
402The workspace plan cannot add another project.
403The key cannot create projects in this workspace.
409The domain is being created by another request.
429Too many requests; wait for the Retry-After window.
GET/projects/{projectId}/status

Get project status

Watch progress only

Returns display-safe setup progress, latest scan state, and next action summaries for a project visible to the automation key.

Request body

None.

Prefer setup.progress.label and setup.progress.description for no-code status displays.

Use actions.summary for a compact client-facing next step.

Success response

{
  "project": {
    "id": "proj_123",
    "name": "Example",
    "primaryDomain": "https://example.com",
    "registeredDomain": "example.com",
    "createdAt": "2026-05-18T10:30:00.000Z"
  },
  "setup": {
    "state": "mapping",
    "summary": "The first website map is in progress.",
    "progress": {
      "label": "Mapping website",
      "description": "BacklinkJet is building the initial site map.",
      "pageCount": 42
    },
    "latestScan": {
      "id": "scan_456",
      "status": "mapping",
      "startedAt": "2026-05-18T10:31:00.000Z",
      "finishedAt": null
    }
  },
  "actions": {
    "needsReview": true,
    "summary": "1 decision needs you. 42 items handled quietly.",
    "items": [
      {
        "id": "protect:open_cluster",
        "label": "Backlink issue cluster",
        "count": 1,
        "href": "/projects/proj_123/backlinks",
        "description": "1 link issue is grouped into one triage pass.",
        "actionLabel": "Open triage"
      }
    ],
    "background": 42
  }
}

Error responses

401Missing, revoked, or malformed automation key.
403The key cannot read projects in this workspace.
404The project does not exist or is outside this workspace.
429Too many requests; wait for the Retry-After window.
Live API playground

Test deployed API calls

Requests are sent to https://backlinkjet.ai/api/v1. The playground loads when this section is in view.

MCP

Model Context Protocol

Connect Model Context Protocol clients to BacklinkJet with the deployed Streamable HTTP endpoint. Use the same automation key in the Authorization: Bearer header; the MCP tools reuse the same project permissions as the public API.

https://backlinkjet.ai/api/mcp

List projects

linkjet_projects_list
Watch progress only

List the BacklinkJet projects visible to the automation key.

Create or reuse project

linkjet_project_create
Start projects and watch progress

Create a project for a domain or return the existing matching project.

Get project status

linkjet_project_status_get
Watch progress only

Read setup progress, latest scan state, and next action summaries for one project.

Endpoint
POST https://backlinkjet.ai/api/mcp
Authorization: Bearer $LINKJET_API_KEY
Accept: application/json, text/event-stream
Content-Type: application/json

Create a project

Use an automation key set to Start projects and watch progress.

curl -X POST \
  -H "Authorization: Bearer $LINKJET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"https://example.com","name":"Example"}' \
  https://backlinkjet.ai/api/v1/projects

Check status

A key set to Watch progress only can read this status. Show setup.progress.label, setup.latestScan.status, and actions.summary in client portals or no-code tools.

curl -H "Authorization: Bearer $LINKJET_API_KEY" \
  https://backlinkjet.ai/api/v1/projects/{projectId}/status

Import the API

Use this URL in tools that accept OpenAPI schemas. It includes the project endpoints and webhook event contracts.

https://backlinkjet.ai/api/v1/openapi.json

Verify webhooks

Verify LinkJet-Signature before trusting a signed webhook delivery. A test delivery can arrive before the first website exists, so treat project details as optional.

import crypto from "node:crypto";

export function verifyLinkJetWebhook(rawBody, headers, secret) {
  const signature = headers["LinkJet-Signature"] || headers["linkjet-signature"] || "";
  const parts = Object.fromEntries(signature.split(",").map((part) => part.split("=")));
  const timestamp = parts.t;
  const expected = crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
  const actualBuffer = Buffer.from(parts.v1 || "", "hex");
  const expectedBuffer = Buffer.from(expected, "hex");
  return actualBuffer.length === expectedBuffer.length && crypto.timingSafeEqual(actualBuffer, expectedBuffer);
}
Webhook reference

Webhook reference

Webhooks send JSON events to your configured URL. Return any 2xx response to acknowledge delivery.

project.changed

Project changed

Delivered when BacklinkJet creates a project through the public API or when relevant project setup data changes.

Use this to refresh portals, client dashboards, or downstream workflows without polling.

{
  "id": "evt_lx0a1b2c",
  "type": "project.changed",
  "createdAt": "2026-05-18T10:32:00.000Z",
  "workspaceId": "ws_123",
  "projectId": "proj_123",
  "data": {
    "action": "created",
    "project": {
      "id": "proj_123",
      "name": "Example",
      "primaryDomain": "https://example.com"
    }
  }
}
webhook.test

Test delivery

Delivered when a user sends a test event from Connected tools to confirm that the destination URL and signing secret work.

Use this while configuring Zapier, Make, n8n, Retool, or a custom endpoint.

{
  "id": "evt_test_123",
  "type": "webhook.test",
  "createdAt": "2026-05-18T10:33:00.000Z",
  "workspaceId": "ws_123",
  "projectId": null,
  "data": {
    "message": "This is a test delivery from BacklinkJet.",
    "project": null
  }
}

Verify webhooks

Verify LinkJet-Signature before trusting a signed webhook delivery. A test delivery can arrive before the first website exists, so treat project details as optional.

import crypto from "node:crypto";

export function verifyLinkJetWebhook(rawBody, headers, secret) {
  const signature = headers["LinkJet-Signature"] || headers["linkjet-signature"] || "";
  const parts = Object.fromEntries(signature.split(",").map((part) => part.split("=")));
  const timestamp = parts.t;
  const expected = crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
  const actualBuffer = Buffer.from(parts.v1 || "", "hex");
  const expectedBuffer = Buffer.from(expected, "hex");
  return actualBuffer.length === expectedBuffer.length && crypto.timingSafeEqual(actualBuffer, expectedBuffer);
}
Errors and limits

Errors and limits

Use status codes for branching and the response body for human-readable diagnostics.

400

The request body is invalid, missing required JSON, or contains a domain BacklinkJet cannot normalize.

Fix the body before retrying.

401

The Authorization header is missing, malformed, revoked, or uses a key BacklinkJet cannot find.

Create or paste a valid automation key.

402

The workspace plan does not allow the requested project creation.

Upgrade the workspace or remove unused projects.

403

The key is valid but does not have the permission required for this endpoint.

Create a key with the right permission.

404

The project does not exist or the key belongs to a workspace that cannot see it.

List projects with the same key and use one of those IDs.

409

BacklinkJet is already creating or normalizing the same project from another request.

Wait briefly, then list projects or read status for the existing domain.

429

The key or workspace has sent too many requests in a short window.

Respect the Retry-After header before sending another request.

Rate limits

When a response is rate-limited, BacklinkJet returns 429 with a Retry-After header. Automation tools should wait for that many seconds before retrying the same request.

Use webhooks for status changes when possible.

Poll project status with a backoff instead of a fixed one-second loop.

Versioning and schema

The public API is served under /api/v1. The OpenAPI document is the source of truth for machines and is updated when endpoint contracts change.

Deprecated response fields remain documented in OpenAPI while clients migrate.

New additive fields can appear without a version bump.

OpenAPI

OpenAPI schema and Swagger editor

Zapier, Make, n8n, Retool, internal dashboards, and client portals can call the same endpoints. Use the OpenAPI JSON when a tool asks for an API schema.

https://backlinkjet.ai/api/v1/openapi.json