Developer documentation
Integrate ScanToSec into your Business tools
Connect your CRM, client portal, hosting platform, or internal tools to ScanToSec through a simple and secure REST API.
Authentication
All protected routes use a Business API key. Send it in the Authorization header with the Bearer scheme. Never expose this key in public or browser-side code.
Authorization: Bearer YOUR_API_KEY
Accept: application/json
The registration route is public; all other documented routes require a valid API key.
https://scantosec.com/api/v1/business/registerCreate a company and API key
Creates a company and returns a secret API key. This public route should only be called from a secure server.
Input parameters
name (required, string, maximum 255 characters) email (required, unique email) password (required, minimum 8 characters) password_confirmation (required, must match password)
JSON response
{ "company": { ... }, "api_key": "prefix.secret" }https://scantosec.com/api/v1/business/account
Get account
Returns the company, active subscription, and current site quota usage.
Input parameters
No parameters.
JSON response
{ "company": { ... }, "subscription": { ... }, "usage": { "sites_used": 2, "site_limit": 50 } }
https://scantosec.com/api/v1/business/plans
Get active plan
Returns the plan attached to the company’s active subscription.
Input parameters
No parameters.
JSON response
{ "data": [ { "id": 2, "name": "Business 100", "price": "719.99" } ] }
https://scantosec.com/api/v1/business/checkout
Create checkout
Creates a Stripe checkout session to purchase an active plan. The mode depends on the plan: one-time payment or recurring subscription according to payment_type. White label can only be requested when the plan allows it.
Input parameters
plan_id (required, integer, active plan) payment_type (required: one_time or subscription) billing_period (required for subscription: 3_months, 6_months, or year) white_label_enabled (optional, boolean)
JSON response
{ "checkout_url": "https://checkout.stripe.com/...", "subscription_id": 42 }
https://scantosec.com/api/v1/business/sites
List sites
Returns company sites with standard pagination.
Input parameters
page (optional) per_page (optional)
JSON response
{ "data": [ { "id": 10, "name": "Client", "domain": "https://client.example" } ], "pagination": { ... } }
https://scantosec.com/api/v1/business/sites
Create a site
Adds an active site to the company portfolio. The domain must be a valid URL and plan quota must be available. The quota check and creation are protected against concurrent requests. Existing domains are returned without creating a duplicate.
Input parameters
name (required, string) domain (required, URL)
JSON response
{ "data": { "id": 10, "name": "Client", "domain": "https://client.example" } }
https://scantosec.com/api/v1/business/sites/{site}/activate
Activate a site
Activates an existing site belonging to the company. Activation is rejected without an active subscription or when it exceeds the plan site quota.
Input parameters
site (required, integer, ID in the URL)\nNo JSON body.
JSON response
{ "data": { "id": 10, "status": "active", ... }, "message": "Site activated successfully." }
https://scantosec.com/api/v1/business/sites/{site}/deactivate
Deactivate a site
Deactivates an existing site belonging to the company. The site data and its reports are not deleted.
Input parameters
site (required, integer, ID in the URL)\nNo JSON body.
JSON response
{ "data": { "id": 10, "status": "inactive", ... }, "message": "Site deactivated successfully." }
https://scantosec.com/api/v1/business/sites/{site}
Delete a site
Permanently deletes a site belonging to the company and reports associated with that site or its domain.
Input parameters
site (required, integer, ID in the URL)\nNo JSON body.
JSON response
{ "message": "Site deleted successfully.", "site_id": 10 }
https://scantosec.com/api/v1/business/scans
Launch a scan
Starts an asynchronous analysis for the active site matching domain. site_id can be provided to select a company site explicitly. The API immediately returns a report UUID to track. If no active site matches, it returns an error and never selects another site automatically. Business API reports are generated in English.
Input parameters
domain (required, URL) cms_type (required, string) site_id (optional, integer) external_reference (optional, string)
JSON response
{ "data": { "uuid": "...", "status": "pending", "site_id": 10 } }
https://scantosec.com/api/v1/business/reports
List reports
Returns company reports with status, details, and pagination.
Input parameters
page/per_page (optional)
JSON response
{ "data": [ { "uuid": "...", "status": "completed" } ], "pagination": { ... } }
https://scantosec.com/api/v1/business/reports/latest
Get latest report
Returns the latest report and a summary of passed and failed tests.
Input parameters
No parameters.
JSON response
{ "data": { "uuid": "...", "status": "completed" }, "summary": { ... } }
https://scantosec.com/api/v1/business/reports/{uuid}
Get a report
Returns one report by UUID and branding information when white label is active.
Input parameters
uuid (required, UUID in the URL)
JSON response
{ "data": { ... }, "branding": { ... } }
https://scantosec.com/api/v1/business/payments
List payments
Returns the company subscription payment history.
Input parameters
page/per_page (optional)
JSON response
{ "data": [ { "amount": "719.99", "status": "paid" } ], "pagination": { ... } }
https://scantosec.com/api/v1/business/sites/remaining
Get remaining quota
Returns used sites, plan limit, and remaining available sites.
Input parameters
No parameters.
JSON response
{ "data": { "sites_used": 2, "site_limit": 50, "sites_remaining": 48 } }
https://scantosec.com/api/v1/business/branding
Get or update branding
GET reads branding configured by the administrator. PUT updates an existing branding only when the active subscription is within its plan period, the plan supports white label, and the administrator has enabled company editing. Companies cannot create branding through the API. Logo uploads must be PNG, JPG, JPEG, or WebP, no larger than 2 MB and exactly 60 × 60 pixels.
Input parameters
PUT: brand_name, primary_color, secondary_color, support_email (optional) logo (optional image file: PNG/JPG/JPEG/WebP, max 2 MB, exactly 60 x 60 px) GET returns 403 when the plan or period is not eligible, and 404 when the administrator has not configured branding. PUT returns 403 when editing is disabled and 404 when branding does not exist.
JSON response
{ "data": { "brand_name": "Client" } }
https://scantosec.com/api/v1/business/stripe/webhookReceive Stripe events
Receives Stripe events for B2B subscriptions and automatically updates payments and subscription status.
No business JSON to build: send the raw Stripe body with the Stripe-Signature header. The signature is verified server-side.
Errors and HTTP status codes
All responses use JSON. 200 means a successful read, 201 a successful creation, and 202 a scan accepted for asynchronous processing. 401: missing, invalid, revoked, or expired API key. 403: inactive Business account, unverified email, or a feature not allowed by the plan. 404: resource or branding not found. 422: invalid parameters, exceeded quota, or site not found. 502: unable to create the Stripe checkout session.
Integration examples
This example reads the connected account. Use the same Authorization header for all protected endpoints.
PHP
$response = Http::withToken($apiKey)->get('https://scantosec.com/api/v1/business/account');
$data = $response->json();Python
import requests
response = requests.get('https://scantosec.com/api/v1/business/account', headers={'Authorization': f'Bearer {api_key}'})
data = response.json()JavaScript
const response = await fetch('https://scantosec.com/api/v1/business/account', {
headers: { Authorization: `Bearer ${apiKey}` }
});
const data = await response.json();ASP.NET
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiKey);
var response = await client.GetAsync("https://scantosec.com/api/v1/business/account");
var data = await response.Content.ReadAsStringAsync();