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.

Authentication

Start with a free account at /app/signup. Once signed in you can mint an API key with a session-authed POST /v1/keys; the plaintext key is returned once, on creation, and never shown again.

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.

Mint an API key (session-authed)
curl -sS -X POST https://api.seekingdatalabs.com/v1/keys \
  --cookie "$SEEKINGDATA_SESSION" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-agent"}'

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; each run is charged from your balance (or, if the balance is short, the response returns a USDC deposit address and a memo instead). 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. 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.

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"

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.

Pentest and consultancy are not self-serve

There is no API that runs a penetration test. A pentest 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.

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.