Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/ironfang:ironfang-security-findings-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Ironfang Security Findings API
version: 0.1.0
summary: External Security Check - verify a domain, run a low-impact external assessment, fix and recheck findings.
description: 'Ironfang Security helps an organisation understand what it exposes to
the internet, fix what matters and keep evidence that it did.'
contact:
name: Ironfang
email: hello@ironfang.uk
url: https://ironfang.com/contact
termsOfService: https://ironfang.com/legal/terms
license:
name: Proprietary - use governed by the Ironfang terms of service
url: https://ironfang.com/legal/terms
servers:
- url: https://api.ironfang.com/security
security:
- bearerAuth: []
tags:
- name: Findings
description: Normalised findings, their evidence, status and rechecks.
paths:
/v1/findings:
get:
tags:
- Findings
operationId: listFindings
summary: List findings
description: Findings across the organisation, most severe first. By default only findings that still ask something of you (open, acknowledged, needs review) are listed; pass `status` to choose.
parameters:
- name: domain_id
in: query
required: false
schema:
type: string
format: uuid
- name: scan_id
in: query
required: false
description: Only findings observed in this scan.
schema:
type: string
format: uuid
- name: status
in: query
required: false
description: Comma-separated statuses, or `all`.
schema:
type: string
- name: severity
in: query
required: false
description: Comma-separated severities.
schema:
type: string
- $ref: '#/components/parameters/Cursor'
- $ref: '#/components/parameters/Limit'
responses:
'200':
description: Findings.
content:
application/json:
schema:
type: object
required:
- items
- next_cursor
properties:
items:
type: array
items:
$ref: '#/components/schemas/FindingSummary'
next_cursor:
type: string
'400':
$ref: '#/components/responses/Problem'
default:
$ref: '#/components/responses/Problem'
/v1/findings/{findingId}:
parameters:
- $ref: '#/components/parameters/FindingId'
get:
tags:
- Findings
operationId: getFinding
summary: Get a finding
description: What was found, why it matters, the evidence, how to fix it and its history.
responses:
'200':
description: The finding.
content:
application/json:
schema:
$ref: '#/components/schemas/Finding'
'404':
$ref: '#/components/responses/Problem'
default:
$ref: '#/components/responses/Problem'
patch:
tags:
- Findings
operationId: updateFinding
summary: Change a finding's status
description: Sets open, acknowledged, accepted_risk or false_positive, with an optional note. `fixed` is only ever set by a scan or recheck that observes the fix.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateFindingRequest'
responses:
'200':
description: The finding.
content:
application/json:
schema:
$ref: '#/components/schemas/Finding'
'404':
$ref: '#/components/responses/Problem'
'422':
$ref: '#/components/responses/Problem'
default:
$ref: '#/components/responses/Problem'
/v1/findings/{findingId}/recheck:
parameters:
- $ref: '#/components/parameters/FindingId'
post:
tags:
- Findings
operationId: recheckFinding
summary: Recheck a finding
description: Repeats the checks behind this finding on its host. If the condition is no longer observed the finding becomes fixed; its evidence and history are kept.
responses:
'202':
description: The recheck scan.
content:
application/json:
schema:
$ref: '#/components/schemas/Scan'
'404':
$ref: '#/components/responses/Problem'
'409':
$ref: '#/components/responses/Problem'
'429':
$ref: '#/components/responses/Problem'
default:
$ref: '#/components/responses/Problem'
components:
schemas:
PassedCheck:
type: object
required:
- check_id
- title
- category
- host
- summary
- docs_url
properties:
check_id:
type: string
title:
type: string
category:
$ref: '#/components/schemas/CheckCategory'
host:
type: string
summary:
type: string
docs_url:
type: string
format: uri
ScanSummary:
type: object
required:
- id
- domain_id
- domain
- kind
- status
- requested_at
- progress
- counts
properties:
id:
type: string
format: uuid
domain_id:
type: string
format: uuid
domain:
type: string
kind:
$ref: '#/components/schemas/ScanKind'
status:
$ref: '#/components/schemas/ScanStatus'
requested_at:
type: string
format: date-time
started_at:
type: string
format: date-time
finished_at:
type: string
format: date-time
duration_ms:
type: integer
progress:
type: object
required:
- total
- completed
properties:
total:
type: integer
completed:
type: integer
counts:
$ref: '#/components/schemas/ScanCounts'
changes:
$ref: '#/components/schemas/ScanChanges'
recheck_finding_id:
type: string
format: uuid
status_reason:
type: string
description: Why a scan was cancelled, stopped or failed.
Evidence:
type: object
required:
- id
- kind
- summary
- data
- captured_at
- scan_id
properties:
id:
type: string
format: uuid
kind:
type: string
enum:
- dns_answer
- certificate
- tls_handshake
- http_response
- tcp_connect
- service_banner
- certificate_transparency
- note
summary:
type: string
data:
type: object
additionalProperties: true
captured_at:
type: string
format: date-time
scan_id:
type: string
format: uuid
Scan:
allOf:
- $ref: '#/components/schemas/ScanSummary'
- type: object
required:
- policy_version
- categories
- findings
- passed_checks
- observations
- errors
- limitations
- recommended_actions
- scanner
- disclaimer
properties:
policy_version:
type: string
requested_by:
$ref: '#/components/schemas/Person'
categories:
type: array
items:
$ref: '#/components/schemas/CategoryResult'
findings:
type: array
description: Findings observed in this scan.
items:
$ref: '#/components/schemas/FindingSummary'
passed_checks:
type: array
items:
$ref: '#/components/schemas/PassedCheck'
observations:
type: array
description: Informational results that are neither a pass nor a finding (e.g. detected technologies).
items:
$ref: '#/components/schemas/CheckNote'
errors:
type: array
description: Checks that could not complete.
items:
$ref: '#/components/schemas/CheckNote'
limitations:
type: array
items:
type: string
recommended_actions:
type: array
items:
$ref: '#/components/schemas/RecommendedAction'
scanner:
$ref: '#/components/schemas/ScannerIdentity'
disclaimer:
type: string
UpdateFindingRequest:
type: object
required:
- status
properties:
status:
type: string
enum:
- open
- acknowledged
- accepted_risk
- false_positive
note:
type: string
maxLength: 1000
FindingStatus:
type: string
enum:
- open
- acknowledged
- fixed
- accepted_risk
- false_positive
- needs_review
ScanChanges:
type: object
required:
- new
- fixed
- reopened
properties:
new:
type: integer
fixed:
type: integer
reopened:
type: integer
FindingKind:
type: string
enum:
- issue
- hardening
- informational
- potential_vulnerability
CategoryResult:
type: object
required:
- category
- title
- status
- passed
- findings
- errors
properties:
category:
$ref: '#/components/schemas/CheckCategory'
title:
type: string
status:
type: string
enum:
- pending
- running
- completed
- failed
- cancelled
passed:
type: integer
findings:
type: integer
errors:
type: integer
FindingEvent:
type: object
required:
- at
- kind
properties:
at:
type: string
format: date-time
kind:
type: string
enum:
- detected
- seen
- status_changed
- recheck_requested
- recheck_fixed
- recheck_still_present
- fixed
- reopened
from_status:
$ref: '#/components/schemas/FindingStatus'
to_status:
$ref: '#/components/schemas/FindingStatus'
actor:
$ref: '#/components/schemas/Person'
note:
type: string
scan_id:
type: string
format: uuid
CheckNote:
type: object
required:
- check_id
- title
- host
- message
properties:
check_id:
type: string
title:
type: string
host:
type: string
message:
type: string
Severity:
type: string
enum:
- critical
- high
- medium
- low
- info
CheckCategory:
type: string
enum:
- dns
- tls
- http
- email
- exposure
- technology
- discovery
ScanStatus:
type: string
enum:
- queued
- running
- completed
- partial
- failed
- cancelled
- killed
Confidence:
type: string
description: How sure Ironfang is. `low` is presented as "potential".
enum:
- confirmed
- high
- medium
- low
Finding:
allOf:
- $ref: '#/components/schemas/FindingSummary'
- type: object
required:
- check
- summary
- why
- fix
- docs_url
- references
- evidence
- history
- recheck
properties:
check:
type: object
required:
- id
- title
properties:
id:
type: string
title:
type: string
summary:
type: string
description: What we found, in general terms.
why:
type: string
description: Why it matters.
fix:
type: string
description: How to fix it. May contain inline `code`.
docs_url:
type: string
format: uri
references:
type: array
items:
type: string
format: uri
cwe:
type: string
evidence:
type: array
items:
$ref: '#/components/schemas/Evidence'
history:
type: array
items:
$ref: '#/components/schemas/FindingEvent'
recheck:
$ref: '#/components/schemas/Recheck'
note:
type: string
description: The latest note recorded with a status change.
FindingSummary:
type: object
required:
- id
- key
- title
- category
- kind
- severity
- confidence
- status
- host
- domain_id
- first_seen_at
- last_seen_at
- verification
properties:
id:
type: string
format: uuid
key:
type: string
description: Catalogue key, e.g. http.hsts_missing.
title:
type: string
category:
$ref: '#/components/schemas/CheckCategory'
kind:
$ref: '#/components/schemas/FindingKind'
severity:
$ref: '#/components/schemas/Severity'
confidence:
$ref: '#/components/schemas/Confidence'
status:
$ref: '#/components/schemas/FindingStatus'
host:
type: string
domain_id:
type: string
format: uuid
detail:
type: string
description: What was observed on this host.
first_seen_at:
type: string
format: date-time
last_seen_at:
type: string
format: date-time
resolved_at:
type: string
format: date-time
verification:
type: string
description: Whether a scan or recheck has confirmed the current state.
enum:
- unverified
- fixed_verified
- still_present
Problem:
type: object
required:
- error
- request_id
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
description: 'Stable error code. Among them: `unauthorized`, `forbidden`,
`not_found`, `validation_failed`, `domain_invalid`,
`domain_exists`, `domain_limit_reached`,
`verification_pending_limit`, `verification_required`,
`already_verified`, `authorisation_required`,
`policy_outdated`, `scan_in_progress`, `scan_cooldown`,
`daily_limit_reached`, `domain_rate_limited`, `scan_not_active`,
`recheck_unavailable`, `recheck_cooldown`, `check_rate_limited`,
`organisation_suspended`, `scans_paused`, `security_disabled`,
`verification_expired`, `verification_unavailable`,
`verification_pending_limit`, `finding_fixed`, `internal`.
From the Ironfang API in front of the service:
`api_keys_not_supported`, `permissions_unavailable`,
`body_too_large`, `invalid_body`, `invalid_tenant`,
`security_unavailable`, `security_timeout`.
'
message:
type: string
docs:
type: string
format: uri
retry_after_seconds:
type: integer
description: Set on cooldowns and rate limits.
request_id:
type: string
Recheck:
type: object
required:
- available
properties:
available:
type: boolean
reason:
type: string
description: Why a recheck cannot start now.
available_at:
type: string
format: date-time
scan_id:
type: string
format: uuid
description: The recheck in progress.
ScanKind:
type: string
enum:
- full
- recheck
ScanCounts:
type: object
required:
- critical
- high
- medium
- low
- info
- passed
- confirmed
- unverified
- errors
properties:
critical:
type: integer
high:
type: integer
medium:
type: integer
low:
type: integer
info:
type: integer
passed:
type: integer
description: Checks that observed a control working.
confirmed:
type: integer
description: Findings with confirmed or high confidence.
unverified:
type: integer
description: Findings with medium or low confidence.
errors:
type: integer
description: Checks that could not complete.
Person:
type: object
required:
- label
properties:
label:
type: string
RecommendedAction:
type: object
required:
- finding_id
- title
- severity
- confidence
- host
- domain_id
- reason
properties:
finding_id:
type: string
format: uuid
title:
type: string
severity:
$ref: '#/components/schemas/Severity'
confidence:
$ref: '#/components/schemas/Confidence'
host:
type: string
domain_id:
type: string
format: uuid
reason:
type: string
ScannerIdentity:
type: object
required:
- user_agent
- info_url
- source_addresses
properties:
user_agent:
type: string
info_url:
type: string
format: uri
source_addresses:
type: array
description: Public addresses scanner traffic comes from, for allowlisting.
items:
type: string
parameters:
Cursor:
name: cursor
in: query
required: false
description: The next_cursor of the previous page.
schema:
type: string
Limit:
name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 25
FindingId:
name: findingId
in: path
required: true
schema:
type: string
format: uuid
responses:
Problem:
description: An error.
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: Warden JWT
description: 'A Warden user token. Each route also requires a tenant permission in
the acting tenant (`X-Ironfang-Tenant`), resolved live from Warden:
reads need `security.read`; everything that changes state needs
`security.write`. A missing permission is 403; a permission lookup
failure is 503. Platform API keys are not accepted yet.
'
externalDocs:
description: Ironfang Security documentation
url: https://ironfang.com/security/docs