v1.0.0
OAS 3.1.0

Serus API

The Serus API lets you integrate Serus security intelligence into your own systems. Use it to verify an API key, start darkweb scans, retrieve scan results, and stream findings as they are discovered.

Authentication

Every request must include a Serus API key in the Authorization header:

Authorization: Bearer ak_...

Create and manage API keys in the Serus dashboard at Settings → Developer → API Keys. When you create a key, choose the permissions it should have and copy the secret immediately — Serus only shows the secret once.

Keys can be edited, rotated, or revoked from the same page. Once you revoke a key, the next request with that key returns 401 invalid_api_key.

Versioning

The current API version is v1. All public endpoints are served from:

https://api.serus.ai/v1

We make additive changes within a major version. Existing endpoints, fields, and errors remain stable until the next major version. See the stability policy for details.

Getting Started

  1. Sign in to the Serus dashboard.
  2. Open Settings → Developer → API Keys.
  3. Create a key with the permissions your integration needs.
  4. Copy the key secret and store it securely.
  5. Call GET /v1/hello to confirm the key works.

Track usage and credit spend in Settings → Developer → API Spend.

Credits

Some API operations consume Serus credits. Starting a new darkweb scan currently costs 0.25 credits. Reading scan results, revealing unmasked scan data, and verifying a key do not consume credits.

If the account or organization tied to the key does not have enough credits, paid endpoints return 402 insufficient_balance. Add credits in the dashboard before retrying.

Rate Limits

Rate limits are applied to the account or organization that owns the API key. Multiple keys for the same account share the same rate-limit allowance.

Limits are tiered by endpoint type and reset every second:

Tier Limit Endpoints
Default 60 req/s GET /v1/hello
Read 7 req/s GET /v1/darkweb/scans/{scanId}
Write 3 req/s POST /v1/darkweb/scans, POST /v1/darkweb/scans/stream

Responses include rate-limit headers:

Header Meaning
X-RateLimit-Limit Maximum requests allowed in the current window.
X-RateLimit-Remaining Requests still available in the current window.
X-RateLimit-Reset Unix timestamp for when the current window resets.

When the limit is exceeded, the API returns 429 rate_limit_error with a standard Retry-After header (seconds to wait).

Errors

Errors return a consistent JSON envelope:

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "API key is invalid, revoked, or expired",
    "request_id": "0193cf9b-..."
  }
}
Field Meaning
type Error category.
code Stable machine-readable error code.
message Human-readable explanation.
request_id Request identifier to include when contacting support.
details Optional validation details, present for some request errors.

Common status codes:

Status Type When
401 authentication_error The key is missing, malformed, invalid, revoked, or expired.
402 insufficient_balance The request requires more credits than are available.
403 feature_not_allowed The key does not include the permission required by the endpoint.
404 invalid_request_error The endpoint or requested resource was not found.
415 invalid_request_error Content-Type is not application/json.
422 invalid_request_error Request body, path, or query validation failed.
429 rate_limit_error The rate limit was exceeded.
5xx internal_error A server-side failure occurred. Retry with backoff.

Permissions

Each Serus API key has one or more permissions. Permissions limit what the key can do. If a key calls an endpoint without the required permission, the API returns 403 feature_not_allowed with code: "scope_not_granted".

Choose permissions when creating or editing a key in Settings → Developer → API Keys.

In API responses these are exposed as the scopes array (for example, in GET /v1/hello) — same concept, kept under that name for OAuth/standards compatibility.

Available Permissions

Permission Allows
account:read Verify the API key and read basic key/account status from GET /v1/hello.
darkweb:scan Start darkweb scans. Also allows reading the scans created by the key.
darkweb:read Fetch darkweb scan results by scan ID.
darkweb:reveal Request unmasked breach data with ?reveal=true. Also allows reading scan results.

Choosing Permissions

Use the smallest set of permissions your integration needs.

Integration Need Recommended Permissions
Verify that a key works account:read
Start scans and poll masked results darkweb:scan
Read existing scan results only darkweb:read
Read unmasked breach values darkweb:read, darkweb:reveal
Start scans and reveal unmasked values darkweb:scan, darkweb:reveal

If a permission is not selectable in the dashboard, the current account or organization does not have access to it. Contact your Serus admin or support contact to enable it.


Quickstart

1. Create an API Key

Sign in to Serus and open Settings → Developer → API Keys.

Click Create key, give the key a recognizable name, choose the permissions your integration needs, and select an expiration. Copy the secret immediately after creation — Serus only shows the secret once.

For a first test, grant account:read. To run darkweb scans, grant darkweb:scan.

2. Verify the Key

Call GET /v1/hello to confirm the key is valid and see the permissions attached to it:

curl https://api.serus.ai/v1/hello \
  -H "Authorization: Bearer ak_..."

Example response:

{
  "subject": "org_3C1xG2fbP68VhAI6oCQl5s01ltf",
  "scopes": ["account:read", "darkweb:scan", "darkweb:read"],
  "credits_remaining": 1000
}

The subject field returns the ID of the Serus account or organization that owns this API key. Personal-account keys return a user ID prefixed with user_; organization keys return an organization ID prefixed with org_. The scopes array lists the permissions granted to the key — same concept as "permissions" in the dashboard, kept under the name scopes for OAuth/standards compatibility.

3. Start a Darkweb Scan

Use POST /v1/darkweb/scans to scan an identifier such as an email, phone number, username, domain, keyword, origin, or password:

curl https://api.serus.ai/v1/darkweb/scans \
  -H "Authorization: Bearer ak_..." \
  -H "Content-Type: application/json" \
  -d '{"identifierType":"email","identifierValue":"jane@example.com"}'

Example response:

{
  "id": "3DJ09m3jBkxrgA31nwfnqdWSBxI",
  "status": "processing",
  "identifierType": "email"
}

Store the id. You will use it to retrieve results.

4. Fetch Results

Poll GET /v1/darkweb/scans/{scanId} until the scan reaches success or failed:

curl https://api.serus.ai/v1/darkweb/scans/3DJ09m3jBkxrgA31nwfnqdWSBxI \
  -H "Authorization: Bearer ak_..."

By default, sensitive breach values are masked. To retrieve unmasked values, call the same endpoint with ?reveal=true using a key that has darkweb:reveal.

5. Monitor Usage

Open Settings → Developer → API Spend to review credit usage by key, feature, and time range. If paid API requests return 402 insufficient_balance, add credits in the dashboard before retrying.


Stability Policy

Serus API versions are designed to be stable for external integrations. We make additive changes within a major version. Existing endpoints, fields, and errors remain stable until the next major version.

Changes We May Make Without Notice

These changes should not break tolerant clients:

Change Client expectation
Add a new endpoint Existing endpoints continue working.
Add a new optional request field Existing requests remain valid.
Add a new response field Ignore unknown fields.
Add a new permission Existing keys and permissions continue working.
Loosen request validation Existing valid requests remain valid.

Changes We Avoid Within A Major Version

Change
Remove or rename a field.
Change a field's type.
Tighten validation for an existing field.
Change the documented status code for an existing response.
Remove or rename an endpoint.
Remove or rename a permission.

Breaking Changes

Breaking changes ship in a new major version such as /v2. When that happens, the previous major version remains supported for a migration window so integrations can move safely.

Server:https://api.serus.ai

Production

Client Libraries

Account

Use account endpoints to verify an API key and inspect the basic status needed before making paid API requests.

Key Verification

Call GET /v1/hello after creating or rotating a key. A successful response confirms that the key is valid and returns:

Field Meaning
subject Identifier of the Serus account or organization that owns this key. Personal-account keys return a user ID prefixed with user_; organization keys return an organization ID prefixed with org_.
scopes Permissions attached to the key.
credits_remaining Credits currently available for paid API operations.

Use this endpoint in deployment checks or health checks for your Serus integration. It does not consume credits.

Account Operations

Verify an API key

Confirms that the API key is valid and returns the key's permissions plus the remaining credit balance for paid API operations.

Responses
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/v1/hello
curl https://api.serus.ai/v1/hello \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
  "subject": "string",
  "scopes": [
    "string"
  ],
  "credits_remaining": 0
}

Darkweb (Collapsed)

Use darkweb endpoints to scan identifiers and retrieve matching breaches or pastes. Supported identifier types are email, phone, username, domain, keyword, origin, and password.

Typical Workflow

  1. Start a scan with POST /v1/darkweb/scans.
  2. Store the returned id.
  3. Poll GET /v1/darkweb/scans/{scanId} until status is success or failed.
  4. Read masked results by default.
  5. Use ?reveal=true only when your integration needs unmasked values and your key has darkweb:reveal.

Scan Cost

Starting a new darkweb scan costs 0.25 credits. If a recent scan for the same identifier is already available, Serus may return that scan instead of starting and charging for a duplicate scan.

If the account or organization tied to the key does not have enough credits, scan endpoints return 402 insufficient_balance.

Masked And Revealed Data

Scan results are masked by default. In masked responses, each breach keeps its field types but replaces sensitive values with null, and extractedData values are masked.

To retrieve unmasked values, call:

GET /v1/darkweb/scans/{scanId}?reveal=true

This requires darkweb:reveal. Reveals are logged for security audit. Use sparingly.

Result Fields

breaches contains matched breach records. Each breach includes:

Field Meaning
breachedData Matched fields for the breach. Values are masked unless reveal=true.
isMasked Whether sensitive values are masked in this response.
breachAuthority Source metadata such as name, logo path, and data classes.

pastes contains matching paste records with source, title, date, and email count.

extractedData summarizes personal information found across all results:

Field Meaning
emails Email addresses.
usernames Usernames or handles.
phones Phone numbers.
names Names.
cryptoAddresses Cryptocurrency wallet addresses.

Streaming Scans

Use POST /v1/darkweb/scans/stream when your application needs live progress instead of polling. The request body is the same as POST /v1/darkweb/scans, and the response is a text/event-stream Server-Sent Events stream.

Connection behavior:

Behavior Value
Maximum stream duration 5 minutes.
Heartbeat Comment frame every 15 seconds.
Cached results Events are emitted immediately and the stream closes.

Event types:

Event When It Fires Data Shape
breach A matching breach was found. Same shape as a breaches[] item.
paste A matching paste was found. Same shape as a pastes[] item.
done Scan finished successfully. { id, status: "completed", totalBreaches, totalPastes }
error The scan failed or the stream could not continue. { id, message }

The stream emits exactly one terminal event — done on success or error on failure — then closes. Cached results are emitted in a single batch followed by done.

Example:

curl -N https://api.serus.ai/v1/darkweb/scans/stream \
  -H "Authorization: Bearer ak_..." \
  -H "Content-Type: application/json" \
  -d '{"identifierType":"email","identifierValue":"jane@example.com"}'