Voltair Webhooks API
The Webhooks API from Voltair — 5 operation(s) for webhooks.
The Webhooks API from Voltair — 5 operation(s) for webhooks.
openapi: 3.0.3
info:
title: Voltair ApiKeys Webhooks 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: Webhooks
paths:
/webhooks:
get:
tags:
- Webhooks
operationId: listWebhooks
summary: List webhooks
parameters:
- $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/Webhook'
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:
- Webhooks
operationId: createWebhook
summary: Create webhook
description: Creates a webhook. The server generates the signing secret.
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateWebhookRequest'
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/Webhook'
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'
/webhooks/{webhookId}:
parameters:
- name: webhookId
in: path
required: true
schema:
type: string
format: uuid
get:
tags:
- Webhooks
operationId: getWebhook
summary: Get webhook
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/Webhook'
'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:
- Webhooks
operationId: updateWebhook
summary: Update webhook
description: Updates a webhook (URL, events, enabled flag). Cannot edit id, organizationId, or secret (use rotate endpoint for secret).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateWebhookRequest'
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/Webhook'
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:
- Webhooks
operationId: deleteWebhook
summary: Delete webhook
description: Soft-deletes a webhook. Delivery history is retained for audit purposes.
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/Webhook'
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'
/webhooks/{webhookId}/rotate-secret:
parameters:
- name: webhookId
in: path
required: true
schema:
type: string
format: uuid
post:
tags:
- Webhooks
operationId: rotateWebhookSecret
summary: Rotate webhook secret
description: Generates a new signing secret. Returns the updated webhook with the new secret.
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
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/Webhook'
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'
/webhooks/{webhookId}/test:
parameters:
- name: webhookId
in: path
required: true
schema:
type: string
format: uuid
post:
tags:
- Webhooks
operationId: testWebhook
summary: Test webhook
description: Sends a test payload to the webhook URL. Returns the delivery result (status code, response time, error).
parameters:
- $ref: '#/components/parameters/IdempotencyKeyHeader'
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/WebhookDelivery'
'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'
/webhooks/{webhookId}/deliveries:
parameters:
- name: webhookId
in: path
required: true
schema:
type: string
format: uuid
get:
tags:
- Webhooks
operationId: listWebhookDeliveries
summary: List webhook deliveries
parameters:
- name: event
in: query
schema:
type: string
description: Filter by webhook event type
- $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/WebhookDelivery'
meta:
$ref: '#/components/schemas/PaginationMeta'
'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:
parameters:
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.
CursorParam:
name: cursor
in: query
schema:
type: string
description: Opaque pagination cursor from a previous response
LimitParam:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 200
description: Page size (default 50, max 200)
responses:
Forbidden:
description: Insufficient permissions
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: Resource not found
headers:
X-Request-Id:
$ref: '#/components/headers/XRequestId'
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'
BadRequest:
description: Bad request or validation error
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'
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'
schemas:
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)
PaginationMeta:
type: object
required:
- cursor
properties:
cursor:
type: string
nullable: true
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
UpdateWebhookRequest:
type: object
properties:
url:
type: string
events:
type: array
items:
$ref: '#/components/schemas/WebhookEvent'
enabled:
type: boolean
CreateWebhookRequest:
type: object
required:
- url
- events
properties:
url:
type: string
events:
type: array
items:
$ref: '#/components/schemas/WebhookEvent'
enabled:
type: boolean
WebhookEvent:
type: string
enum:
- mission.scheduled
- mission.started
- mission.completed
- mission.failed
- processing.started
- processing.completed
WebhookDelivery:
type: object
required:
- id
- organizationId
- webhookId
- event
- timestamp
- statusCode
- responseTimeMs
- error
properties:
id:
type: string
format: uuid
organizationId:
type: string
format: uuid
webhookId:
type: string
format: uuid
event:
$ref: '#/components/schemas/WebhookEvent'
timestamp:
type: number
statusCode:
type: integer
nullable: true
responseTimeMs:
type: integer
nullable: true
error:
type: string
nullable: true
Webhook:
type: object
required:
- id
- organizationId
- url
- secret
- events
- enabled
- deletedAt
- createdAt
properties:
id:
type: string
format: uuid
organizationId:
type: string
format: uuid
url:
type: string
secret:
type: string
description: HMAC-SHA256 signing secret
events:
type: array
items:
$ref: '#/components/schemas/WebhookEvent'
enabled:
type: boolean
deletedAt:
type: number
nullable: true
createdAt:
type: number
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