Voltair Sites API
The Sites API from Voltair — 3 operation(s) for sites.
The Sites API from Voltair — 3 operation(s) for sites.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/voltair-sites-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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: Voltair ApiKeys Sites API
version: 0.1.0
description: 'Infrastructure inspection platform API. All endpoints are scoped to the authenticated organization via Bearer JWT or API key.
All timestamp fields on this API (createdAt, updatedAt, scheduledFor, capturedAt, expiresAt, deletedAt, etc.) are Unix timestamps in milliseconds since the epoch (UTC). Both request and response bodies use this representation.'
servers:
- url: /
security:
- BearerAuth: []
- ApiKeyAuth: []
tags:
- name: Sites
paths:
/sites:
get:
tags:
- Sites
operationId: listSites
summary: List sites
parameters:
- name: clusterId
in: query
schema:
type: string
format: uuid
- name: unclustered
in: query
schema:
type: boolean
description: If true, return only sites with no cluster assignment. Cannot be combined with clusterId.
- name: externalId
in: query
schema:
type: string
description: Filter by customer-facing external identifier
- name: tags
in: query
schema:
type: string
description: Comma-separated tag values
- name: priority
in: query
schema:
type: string
description: Comma-separated priorities (high, medium, low, none)
- name: siteType
in: query
schema:
type: string
description: Comma-separated site types (e.g. substation,distribution_pole)
- name: geometryType
in: query
schema:
type: string
enum:
- Point
- LineString
- Polygon
- MultiLineString
- MultiPolygon
description: Filter by the GeoJSON geometry type of the site
- name: q
in: query
schema:
type: string
description: Case-insensitive substring match against name, externalId, and description
- name: bounds
in: query
schema:
type: string
description: 'Bounding box: minLng,minLat,maxLng,maxLat'
- $ref: '#/components/parameters/LimitParam'
- $ref: '#/components/parameters/CursorParam'
responses:
'200':
description: Success
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- meta
properties:
data:
type: array
items:
$ref: '#/components/schemas/Site'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
post:
tags:
- Sites
operationId: createSite
summary: Create site
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSiteRequest'
responses:
'201':
description: Created
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- transactionId
properties:
data:
$ref: '#/components/schemas/Site'
transactionId:
type: string
format: uuid
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
/sites/bulk:
post:
tags:
- Sites
operationId: bulkCreateSites
summary: Bulk create sites
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- sites
properties:
sites:
type: array
items:
$ref: '#/components/schemas/CreateSiteRequest'
responses:
'201':
description: Created
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- transactionId
properties:
data:
type: array
items:
$ref: '#/components/schemas/Site'
transactionId:
type: string
format: uuid
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
delete:
tags:
- Sites
operationId: bulkDeleteSites
summary: Bulk delete sites
description: 'Soft-deletes an array of sites by ID. The `ids` array must be
non-empty and at most 10000 entries; callers that need to delete more
should submit multiple requests.'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- ids
properties:
ids:
type: array
minItems: 1
maxItems: 10000
items:
type: string
format: uuid
responses:
'200':
description: Success
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- transactionId
properties:
data:
type: array
items:
$ref: '#/components/schemas/Site'
transactionId:
type: string
format: uuid
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
/sites/{siteId}:
parameters:
- name: siteId
in: path
required: true
schema:
type: string
format: uuid
get:
tags:
- Sites
operationId: getSite
summary: Get site
responses:
'200':
description: Success
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/Site'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
put:
tags:
- Sites
operationId: updateSite
summary: Update site
description: Updates a site. Cannot edit id or organizationId.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSiteRequest'
responses:
'200':
description: Success
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- transactionId
properties:
data:
$ref: '#/components/schemas/Site'
transactionId:
type: string
format: uuid
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
delete:
tags:
- Sites
operationId: deleteSite
summary: Delete site
description: Soft-deletes a site by setting deleted_at.
responses:
'200':
description: Success
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
type: object
required:
- data
- transactionId
properties:
data:
$ref: '#/components/schemas/Site'
transactionId:
type: string
format: uuid
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalError'
components:
schemas:
Site:
type: object
required:
- type
- id
- organizationId
- name
- siteType
- geometry
- deletedAt
- createdAt
- updatedAt
properties:
type:
type: string
enum:
- Feature
description: GeoJSON Feature type constant
id:
type: string
format: uuid
organizationId:
type: string
format: uuid
externalId:
type: string
description: Optional customer-facing identifier
name:
type: string
siteType:
$ref: '#/components/schemas/SiteType'
description:
type: string
tags:
type: array
items:
type: string
clusterId:
type: string
format: uuid
cameraOrientation:
$ref: '#/components/schemas/CameraOrientation'
geometry:
$ref: '#/components/schemas/SiteGeometry'
properties:
$ref: '#/components/schemas/SiteProperties'
priority:
$ref: '#/components/schemas/AssetPriority'
description: Read-only; derived from highest-severity defect
deletedAt:
type:
- number
- 'null'
createdAt:
type: number
updatedAt:
type: number
PolygonGeometry:
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- Polygon
coordinates:
type: array
items:
type: array
items:
type: array
items:
type: number
minItems: 2
maxItems: 3
minItems: 4
SiteType:
type: string
description: Union of PointSiteType, AreaSiteType, and LineSiteType
enum:
- distribution_pole
- transmission_pole
- substation
- utility_substation
- transmission_line
- distribution_line
- pipeline
- railway
- road
- other
AssetPriority:
type: string
enum:
- high
- medium
- low
- none
PointGeometry:
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- Point
coordinates:
type: array
description: '[longitude, latitude] or [longitude, latitude, altitude]'
items:
type: number
minItems: 2
maxItems: 3
CameraOrientation:
type: object
required:
- center
- zoom
- bearing
- pitch
properties:
center:
type: array
description: '[longitude, latitude]'
items:
type: number
minItems: 2
maxItems: 2
zoom:
type: number
bearing:
type: number
pitch:
type: number
UpdateSiteRequest:
type: object
properties:
externalId:
type: string
description: Optional customer-facing identifier
name:
type: string
siteType:
$ref: '#/components/schemas/SiteType'
description:
type: string
tags:
type: array
items:
type: string
clusterId:
type: string
format: uuid
cameraOrientation:
$ref: '#/components/schemas/CameraOrientation'
geometry:
$ref: '#/components/schemas/SiteGeometry'
properties:
$ref: '#/components/schemas/SiteProperties'
LineStringGeometry:
type: object
required:
- type
- coordinates
properties:
type:
type: string
enum:
- LineString
coordinates:
type: array
items:
type: array
items:
type: number
minItems: 2
maxItems: 3
minItems: 2
PaginationMeta:
type: object
required:
- cursor
properties:
cursor:
type:
- string
- 'null'
description: Opaque cursor for the next page; null when no more results
total:
type: integer
description: Total matching results across all pages; included when cheaply computable
SiteProperties:
description: Site-type-specific properties; currently only LineProperties
oneOf:
- $ref: '#/components/schemas/LineProperties'
SiteGeometry:
description: GeoJSON geometry for sites (Point, LineString, or Polygon)
oneOf:
- $ref: '#/components/schemas/PointGeometry'
- $ref: '#/components/schemas/LineStringGeometry'
- $ref: '#/components/schemas/PolygonGeometry'
discriminator:
propertyName: type
mapping:
Point: '#/components/schemas/PointGeometry'
LineString: '#/components/schemas/LineStringGeometry'
Polygon: '#/components/schemas/PolygonGeometry'
LineProperties:
type: object
required:
- geometryType
- width
properties:
geometryType:
type: string
enum:
- line
width:
type: number
ErrorResponse:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
description: Machine-readable error code
message:
type: string
description: Human-readable description
details:
type: object
additionalProperties: true
description: Optional structured info (e.g. field-level validation errors, conflictingEventIds)
CreateSiteRequest:
type: object
required:
- name
- siteType
- geometry
properties:
externalId:
type: string
description: Optional customer-facing identifier
name:
type: string
siteType:
$ref: '#/components/schemas/SiteType'
description:
type: string
tags:
type: array
items:
type: string
clusterId:
type: string
format: uuid
cameraOrientation:
$ref: '#/components/schemas/CameraOrientation'
geometry:
$ref: '#/components/schemas/SiteGeometry'
properties:
$ref: '#/components/schemas/SiteProperties'
parameters:
LimitParam:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 200
description: Page size (default 50, max 200)
CursorParam:
name: cursor
in: query
schema:
type: string
description: Opaque pagination cursor from a previous response
IdempotencyKeyHeader:
name: Idempotency-Key
in: header
required: false
schema:
type: string
format: uuid
description: Idempotency key for POST requests. If a transaction with the same key already exists for the org, the server returns the original response without re-executing. Keys are valid for 48 hours.
responses:
NotFound:
description: Resource not found
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InternalError:
description: Internal server error
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
TooManyRequests:
description: Rate limit exceeded
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
X-RateLimit-Limit:
schema:
type: integer
description: Maximum requests per window
X-RateLimit-Remaining:
schema:
type: integer
description: Requests remaining in current window
X-RateLimit-Reset:
schema:
type: number
description: Unix timestamp (ms) when the window resets
Retry-After:
schema:
type: integer
description: Seconds until the next rate limit window
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Authentication required
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Conflict:
description: Conflict (duplicate resource, in-use resource, or undo conflict)
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
BadRequest:
description: Bad request or validation error
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: Insufficient permissions
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
XRequestId:
description: Unique request identifier (UUID)
schema:
type: string
format: uuid
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: Cognito JWT access token
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: Organization-scoped API key