Reports API

The Sightline reporting API

Sightline is an agent-native reporting API. You commission a report on a domain you own, poll until it is ready, then read it back as structured findings, a full report, or a PDF. Reports are paid per run from a prepaid USDC credit balance. Every response ships the same {data, meta, provenance} envelope, never bare data.

Base URL: https://api.seekingdatalabs.com. Every path below is relative to it. All examples use curl; substitute your own domain, report id, and API key.

Quick start

  1. Create a key. Sign in to the portal and create an API key on the Security page. It is shown once, on creation.
  2. Run a report on a verified domain you own: POST /v1/analysis/run. The response carries a report_id.
  3. Poll GET /v1/analysis/report/{id} until its status is ready.
  4. Fetch the findings, or the PDF.
The whole flow, end to end
# 1. The key from the portal Security page
export SEEKINGDATA_KEY="paste-your-key-here"

# 2. Run a report; note the report_id in the response
curl -sS -X POST \
  "https://api.seekingdatalabs.com/v1/analysis/run?domain=example.com&report_type=analyzer" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

# 3. Poll until "status" is "ready"
curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

# 4. Fetch the findings, then the PDF
curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f/findings" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"
curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f/pdf" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY" -o report.pdf

How a run is paid for is under Paying for a run.

Authentication

Sign in to the portal at /app/login/ and create an API key on the Security page; the plaintext key is shown once, on creation, and never again. Self-registration is closed for now: to ask for an account, write to [email protected].

Every request is authenticated one of two ways: the browser session cookie (for calls made from the signed-in portal), or a Bearer API key in the Authorization header (for calls made by your own code or an agent). The examples below use a Bearer key.

The reporting flow

A report goes through three steps: commission a run, poll it until it is ready, then fetch the result. Runs are asynchronous: the run call returns immediately with a report id and a status, and the report fills in as the fleet works.

1. Run a report

POST /v1/analysis/run commissions a run. It requires a verified domain you own and available credit (see Paying for a run). The report_type query parameter selects the product: analyzer for the website audit (the default) or asvs for the OWASP ASVS security posture report. Any other value folds to analyzer. The asvs report needs an active security subscription.

Commission a run
curl -sS -X POST \
  "https://api.seekingdatalabs.com/v1/analysis/run?domain=example.com&report_type=analyzer" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

The response carries a report_id and a status.

2. Poll until ready

GET /v1/analysis/reports lists your runs. Fetch a single run with GET /v1/analysis/report/{id} and poll it until its status is ready.

The listing answers with the current report for each domain. Once a newer report replaces an older one, the older is marked superseded and left out of the list; pass ?archived=1 to get the whole history back, with an archived_at on every superseded run. Superseded reports keep resolving by id and by share link, so anything you have already handed out still opens.

List your runs, then poll one
curl -sS "https://api.seekingdatalabs.com/v1/analysis/reports" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

3. Fetch the report

Once a run is ready, three views are available:

  • GET /v1/analysis/report/{id}, the full report envelope.
  • GET /v1/analysis/report/{id}/findings, the structured findings for the run.
  • GET /v1/analysis/report/{id}/pdf, the report as a PDF.
Read the findings, then the PDF
curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f/findings" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

curl -sS "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f/pdf" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY" \
  -o report.pdf

Sharing a report

POST /v1/analysis/report/{id}/share mints an unguessable share token; the matching DELETE revokes it. Anyone holding the token can then read the report with GET /v1/analysis/shared/{token}, which is public and needs no authentication. The token is the whole credential, so share it deliberately.

Mint a share token, then read it with no auth
curl -sS -X POST \
  "https://api.seekingdatalabs.com/v1/analysis/report/rep-0a1b2c3d4e5f/share" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

# The returned token reads publicly, no key:
curl -sS "https://api.seekingdatalabs.com/v1/analysis/shared/$SHARE_TOKEN"

Paying for a run

Each run is charged from your balance (or, if the balance is short, the response returns a USDC deposit address and a memo instead). When the balance covers the run it is queued straight away; when it does not, the run is held awaiting_payment and the response returns the deposit address and the memo to send USDC to.

Credit balance and transactions

GET /v1/credits returns your balance and the recent movements that built it. The balance is the running sum of an append-only ledger, so the numbers always reconcile. Key fields:

  • balance_atomic, the running total over the whole ledger, in atomic USDC units (millionths). balance_usd is the same figure in dollars.
  • entries[], the recent movements, each with an id, created_at, a signed delta_atomic, a direction (credit or debit), a reason, a ref, and an actor.
  • next_before, the pagination cursor. Pass it back as before= to fetch the next page; it is null on the last page.
  • topup, how to add credit: a deposit address and the exact top-<account-id> memo that credits your account (USDC on Solana). The memo is served complete; send it exactly, or the deposit cannot be matched to your account.
Read the ledger, then page with the cursor
curl -sS "https://api.seekingdatalabs.com/v1/credits?limit=25" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

# Next page: pass the previous response's next_before
curl -sS "https://api.seekingdatalabs.com/v1/credits?limit=25&before=1024" \
  -H "Authorization: Bearer $SEEKINGDATA_KEY"

Reports and priced data calls are paid from this balance by default; a call your plan already covers stays free. Credit lands once a top-up transfer confirms on chain, not the instant it is sent.

Security assessments and consultancy are not self-serve

There is no API that runs a security assessment (a penetration test only with written authorisation for active testing). A security assessment is a scoped, authorized engagement: it runs only after an offline authorization and contract, and is dispatched internally by an operator. Nothing you can call here starts one.

What you can do through the API is record intent. A POST /v1/requests files a request for a human operator to review; it changes nothing about your account and starts no work. The body takes a kind of pentest, pentest_discussion, or consultancy, a domain (required for the pentest kinds; omitted for consultancy), and an optional free-text detail. The pentest kind names the contracted security assessment; the same request covers the vulnerability scan and, with authorisation, the penetration test.

Record intent for a human operator to review
curl -sS -X POST https://api.seekingdatalabs.com/v1/requests \
  -H "Authorization: Bearer $SEEKINGDATA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"pentest","domain":"example.com","detail":"Pre-launch review of the checkout flow."}'

A repeat request for the same domain and kind stacks rather than duplicating. An operator picks it up from there.