Namesight
Try free

REST API

Run scans from your own code. The API is available on the Pro plan and above, authenticates with a bearer key, and is paid for with credits.

Last updated: 6 September 2026

Authentication

Create a key under Settings → API keys. The plaintext key is shown once and cannot be recovered afterwards; only its prefix is stored in a readable form. Send it as a bearer token on every request.

curl https://api.namesight.app/v1/usage \
  -H "Authorization: Bearer ns_live_..."

Every key carries a set of scopes. A request that needs a scope the key does not have is refused with 403, so a key you hand to a read-only integration cannot start a paid scan.

ScopeGrants
scans:writePOST /v1/scans — starting a scan, which spends credits
scans:readGET /v1/scans, GET /v1/scans/{id}, GET /v1/usage
reference:readThe /v1/ref/* lookup endpoints
reports:writePOST /v1/scans/{id}/shares — minting a public share link
ideas:writePOST /v1/ideas — the name generator
projects:readGET /v1/projects — listing projects so a scan can be filed
webhooks:manageThe /v1/webhooks endpoints

Credits and quota

Every scan is paid for with credits, whether you start it here or in the web app. A scan costs the sum of the modules it runs: 100 credits with all five default modules, and less when you leave one out. Your plan grants a credit allowance each month; unspent credits roll over.

The charge is written before any work is queued, so a scan that cannot be paid for never runs and never leaves a row behind. If queueing fails after the charge, the credits are refunded automatically.

  • Balance too low → 429 with a problem body explaining the shortfall
  • Plan without API access → 402 and an upgrade URL
  • Credit spending switched off for the workspace → 403

Starting a scan

POST /v1/scans queues a scan and answers 202 straight away. Scanning is asynchronous: the response carries a scanId, not the result.

curl -X POST https://api.namesight.app/v1/scans \
  -H "Authorization: Bearer ns_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "lumina labs",
    "regions": ["TR", "EM", "US"],
    "niceClasses": [9, 41],
    "tlds": ["com", "io"],
    "modules": ["trademark", "domain", "social"]
  }'
{ "scanId": "scn_...", "totalJobs": 12, "creditsSpent": 100, "balance": 1900 }
FieldRequiredMeaning
nameyesThe brand name to check, 2–64 characters
regionsnoTrademark offices to search. Defaults to your workspace default
niceClassesnoGoods/services classes 1–45. Narrows trademark hits to real conflicts
tldsnoDomain extensions, without the leading dot
modulesnotrademark, domain, social, dev, appstore
adaptersnoRestrict to specific source adapters by id
projectIdnoFile the scan under an existing project
options.similarSearchnoFuzzy trademark query for near-miss marks (Pro and above)

Reading the result

Poll GET /v1/scans/{id} until status is completed or completed_partial. A typical scan finishes in under a minute; poll about once a second and widen the interval as you wait, so a long scan does not eat your rate limit.

curl https://api.namesight.app/v1/scans/scn_... \
  -H "Authorization: Bearer ns_live_..."
statusMeans
queuedAccepted, no source contacted yet
runningSome checks are done; doneJobs / totalJobs shows progress
completedEvery check finished
completed_partialFinished, but at least one source could not be verified
failedThe scan could not be run

Each entry in checks is one source answering about one target, with its own verdict, the sourceUrl it was read from and the fetchedAt timestamp. The summary object appears once the scan finishes and carries the score, the risk band and the trademark tally.

verdictMeans
availableThe source says the name is free
takenIn use — a registered handle, a resolving domain
conflictA live trademark that overlaps the requested classes
riskyIn use in a way that may or may not block you
unknownThe source could not be verified
errorThe source failed; errorCode says how

Reference data

Four lookup endpoints describe what a scan request may contain. They need the reference:read scope and cost nothing.

EndpointReturns
GET /v1/ref/nice-classesThe 45 Nice classification classes
GET /v1/ref/regionsTrademark offices a scan can search
GET /v1/ref/tldsDomain extensions grouped by tier
GET /v1/ref/adaptersEvery source adapter, with its module

Errors and rate limits

Errors are RFC 9457 problem documents sent as application/problem+json. The type field identifies the failure, detail explains it, and some carry extras such as upgradeUrl.

{
  "type": "https://namesight.app/errors/quota-exceeded",
  "title": "Quota exceeded",
  "status": 429,
  "detail": "Not enough credits (balance 0, need 100). Top up or switch off a module to continue."
}
StatusWhen
400The request body did not validate
401Key missing, unknown, revoked or expired
402The plan does not include the public API
403The key lacks a scope, or credit spending is off
404No such scan in this workspace
403 (key-cap-exceeded)This key's monthly credit cap is reached; raise it under Settings → API keys
409An Idempotency-Key was reused with a different body
429Rate limit or credit balance exceeded

Rate limits are counted per key over a sliding minute and reported on every response, so you can back off before being refused.

x-ratelimit-limit: 60
x-ratelimit-remaining: 58
x-ratelimit-reset: 41

Acting on a scan, and the rest

Beyond starting and reading a scan, a key can run it again, retry the sources that could not answer, delete it, share its report, list the workspace's projects and generate name ideas. Each needs the scope shown.

Method and pathScopeDoes
POST /v1/scans/{id}/rescanscans:writeStarts a new scan with the same name and settings. Priced like a new scan; the original is kept.
POST /v1/scans/{id}/retry-unknownsscans:writeQueues again only the checks that ended unknown or errored, bypassing the cache. Free.
DELETE /v1/scans/{id}scans:writeRemoves the scan, its checks and its share links. Credits are not refunded.
POST /v1/scans/{id}/sharesreports:writeReturns a public URL for the report. Anyone holding it can read the report; the plan caps how long it lives.
GET /v1/projectsprojects:readThe workspace's projects, with their default classes, offices and TLDs.
POST /v1/ideasideas:writeRuns the name generator from a brief, a seed name or themes. Free.
GET /v1/usage/eventsscans:readEvery API call the workspace made in the last days, failures included.

Retrying safely: send an Idempotency-Key header (any unique string) with POST /v1/scans or a rescan. A retry that carries the same key within 24 hours replays the first answer — the response says Idempotent-Replayed: true — instead of starting and charging a second scan. The same key with a different body is refused with 409.

curl -X POST https://api.namesight.app/v1/scans \
  -H "Authorization: Bearer ns_live_..." \
  -H "Idempotency-Key: 4f7c2c1e-order-1187" \
  -H "Content-Type: application/json" \
  -d '{"name":"Lumina Labs","modules":["trademark","domain"]}'

Waiting without polling: GET /v1/scans/{id}?wait=60000 holds the request until the scan finishes or the wait (at most 60 seconds) elapses, then answers with the scan as it stands. One request, one rate-limit slot, no loop.

Paging: GET /v1/scans answers with items and nextCursor. Pass nextCursor back as cursor for the next page; null means the last page. status filters by one or more comma-separated statuses.

Webhooks

Instead of polling, register an https endpoint and receive a signed POST when a scan finishes. Endpoints are managed under Settings → API or through /v1/webhooks with the webhooks:manage scope; a workspace may hold ten. The signing secret is shown once, at creation and on rotate.

EventWhendata carries
scan.completedA scan reached completed, completed_partial or failedscanId, status, kind, rawName, queryName, projectId, score, band, unknownCount, trademarkLiveConflicts, totalJobs, doneJobs, createdAt, completedAt, url

Every delivery carries four headers: x-namesight-event, x-namesight-delivery (the same id on every retry, so you can deduplicate), x-namesight-timestamp (unix seconds) and x-namesight-signature. The signature is v1= followed by the hex HMAC-SHA256 of "<timestamp>.<raw body>" under your secret. Verify it against the raw request body, and reject timestamps older than five minutes.

import { createHmac, timingSafeEqual } from "node:crypto";

// Express-style handler; keep the RAW body — a re-serialised JSON will not match.
app.post("/hooks/namesight", express.raw({ type: "*/*" }), (req, res) => {
  const ts = req.header("x-namesight-timestamp");
  const sig = req.header("x-namesight-signature");            // "v1=<hex>"
  const body = req.body.toString("utf8");
  const expected = "v1=" + createHmac("sha256", process.env.NAMESIGHT_WEBHOOK_SECRET)
    .update(`${ts}.${body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  if (!fresh || expected.length !== sig.length || !timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
    return res.status(401).end();
  }
  const event = JSON.parse(body);                              // { id, event, createdAt, test, data }
  res.status(202).end();                                       // ack first, work later
  if (!event.test) handleScanCompleted(event.data);            // data.scanId, data.status, data.score, data.url
});

Answer with any 2xx within ten seconds and do the work afterwards. Anything else is retried four more times, after 30 seconds, 2, 10 and 60 minutes. Ten deliveries that fail every attempt in a row switch the endpoint off; re-enabling it clears the count. The Test button sends a synthetic scan.completed with test: true.

OpenAPI

The full machine-readable description is served at /v1/openapi.json. It needs no authentication, so you can generate a client from it before you have a key.