openapi: 3.2.0
info:
title: Honeycomb Anomaly Detection API
version: 1.0.0
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
contact:
email: support@honeycomb.io
description: 'The API allows programmatic management of many resources within Honeycomb.
Please report any discrepancies with actual API behavior in Pollinators Slack or to Honeycomb Support.
'
servers:
- url: https://api.honeycomb.io
- url: https://api.eu1.honeycomb.io
tags:
- name: Anomaly Detection
description: 'Anomaly Detection is in public beta. Endpoints and response shapes may change.
Anomaly Detection identifies Signals - patterns in your services that deviate from their historical baseline - and can notify Recipients when a Signal turns anomalous.
Each Signal is scoped to a service in a dataset and monitors one of the following:
- **`error_rate`**: The fraction of erroring requests, compared to a trained normal band.
- **`presence`**: Whether the service is emitting spans at all.
Signals progress through the following statuses:
- **`onboarding`**: The Signal has been created but does not yet have enough data to train.
- **`normal`**: The Signal is trained and monitoring for anomalies.
- **`anomalous`**: The Signal has detected an anomaly.
- **`off`**: The Signal has been disabled and will not fire.
- **`ineligible`**: The Signal cannot train because its service is not sending enough traffic to establish a reliable baseline.
This API allows you to list Signals, retrieve a Signal with its assigned Recipients, page through a Signal''s historical anomalies, and update a Signal''s enabled state, sensitivity, and Recipient assignments.
## Authorization
The API key must have the **Manage Signals** permission. Learn more about [API keys here](https://docs.honeycomb.io/configure/environments/manage-api-keys/).
'
paths:
/1/signals:
get:
security:
- configuration_key: []
summary: List All Signals
description: 'List Signals in the environment associated with your API key. Signals are returned in cursor-paginated pages and can be filtered by service, dataset, kind, status, and whether they are currently anomalous.
'
tags:
- Anomaly Detection
operationId: listSignals
x-mint:
metadata:
tag: Beta
parameters:
- $ref: '#/components/parameters/PaginationCursor'
- $ref: '#/components/parameters/PaginationSize'
- in: query
name: service_name
description: Restrict results to Signals for a single service.
schema:
type: string
example: checkout-api
- in: query
name: dataset_slug
description: Restrict results to Signals in a single dataset.
schema:
type: string
example: checkout-api
- in: query
name: measured_signal
description: Restrict results to Signals of the given kind.
schema:
$ref: '#/components/schemas/AnomalySignal'
- in: query
name: status
description: 'Restrict results to Signals in the given status.
When `status` is provided, it takes precedence over `currently_anomalous`.
'
schema:
type: string
enum:
- onboarding
- normal
- anomalous
- ineligible
- 'off'
- in: query
name: currently_anomalous
description: 'When `true`, only return Signals that are currently in an anomalous state.
This parameter is ignored when `status` is provided (use `status=anomalous` instead).
'
schema:
type: boolean
responses:
'200':
description: Success
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedSignalsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationFailed'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/GenericError'
/1/signals/{id}:
parameters:
- name: id
description: The unique identifier (ID) of a Signal.
in: path
required: true
schema:
type: string
get:
security:
- configuration_key: []
summary: Get a Signal
description: 'Fetch a Signal by ID, including the Recipients assigned to it.
'
tags:
- Anomaly Detection
operationId: getSignal
x-mint:
metadata:
tag: Beta
responses:
'200':
description: Success
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/SignalDetailResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/GenericError'
put:
security:
- configuration_key: []
summary: Update a Signal
description: 'Update a Signal by ID. All fields in the body are optional; only the fields you supply
are applied.
- `enabled`: Toggles the Signal on or off. Re-enabling a Signal that has already trained puts it back into `normal`; otherwise it returns to `onboarding`.
- `sensitivity`: Sets how far a measurement must deviate from the trained normal band before the Signal fires. Not applicable to `presence` Signals, and cannot be set on a Signal that has not yet trained.
- `recipients`: Replaces the Signal''s Recipient set. An empty array clears all Recipients. Modifying Recipients requires the **Manage Recipients** permission in addition to **Manage Signals**.
'
tags:
- Anomaly Detection
operationId: updateSignal
x-mint:
metadata:
tag: Beta
requestBody:
description: Fields to update on the Signal. All fields are optional.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSignalRequest'
responses:
'200':
description: Success
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/SignalDetailResponse'
'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'
'422':
$ref: '#/components/responses/ValidationFailed'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/GenericError'
/1/signals/{id}/historical_anomalies:
parameters:
- name: id
description: The unique identifier (ID) of a Signal.
in: path
required: true
schema:
type: string
get:
security:
- configuration_key: []
summary: List Historical Anomalies
description: 'List anomalies that a Signal has resolved within a bounded time window. Anomalies are returned in cursor-paginated pages, most recent first. `start_time` and `end_time` are required and must span no more than 30 days.
'
tags:
- Anomaly Detection
operationId: listSignalHistoricalAnomalies
x-mint:
metadata:
tag: Beta
parameters:
- in: query
name: start_time
required: true
description: Start of the query window, in seconds since UNIX epoch.
schema:
type: integer
example: 1740787200
- in: query
name: end_time
required: true
description: End of the query window, in seconds since UNIX epoch. Must be after `start_time` and within 30 days of it.
schema:
type: integer
example: 1741392000
- $ref: '#/components/parameters/PaginationCursor'
- $ref: '#/components/parameters/PaginationSize'
responses:
'200':
description: Success
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedHistoricalAnomaliesResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationFailed'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/GenericError'
components:
parameters:
PaginationSize:
name: page[size]
description: The number of entries to include per response. Maximum value is 100.
in: query
schema:
type: number
minimum: 1
maximum: 100
default: 20
example: 10
PaginationCursor:
name: page[after]
description: 'The string value of the `next` attribute from a previous result page.
The cursor value must be empty or omitted for the first request of a cursor-paginated query.
'
in: query
schema:
type: string
example: eyxJjcmAVhdGVkX
schemas:
PaginationLinks:
type: object
description: Links to iterate through the pages of results.
required:
- next
properties:
next:
type:
- string
- 'null'
description: The URL for the next page of results.
readOnly: true
example: /2/teams/my-team/api-keys?page[after]=3025fa645ad1100d&page[size]=10
Error:
x-tags:
- Errors
type: object
description: A legacy error, containing only a textual description.
properties:
error:
type: string
readOnly: true
AnomalySignal:
type: string
description: 'The kind of measurement the Signal is trained on.
- `error_rate`: The fraction of erroring requests for the service.
- `presence`: Whether the service is producing spans.
'
enum:
- error_rate
- presence
example: error_rate
PaginatedSignalsResponse:
type: object
description: A page of Signals.
required:
- signals
properties:
signals:
type: array
description: The Signals in this page.
items:
$ref: '#/components/schemas/Signal'
links:
$ref: '#/components/schemas/PaginationLinks'
NotificationRecipientDetails:
type: object
properties:
pagerduty_severity:
description: 'When using a Recipient of `type = "pagerduty"`, the severity of the alert can be specified.
'
type: string
default: critical
enum:
- critical
- error
- warning
- info
variables:
description: 'When using a Recipient of `type = "webhook"`, the alert-level variables can be specified.
'
type: array
items:
type: object
required:
- name
properties:
name:
type: string
pattern: ^[a-z](?:[a-zA-Z0-9]+$)?$
maxLength: 64
example: severity
value:
type: string
maxLength: 256
example: warning
muted:
type: boolean
description: 'When `true`, the Recipient is muted for this alert and will not receive notifications.
Only applies to Recipients assigned to a Signal via the Anomaly Detection API.
'
JSONAPIError:
x-tags:
- Errors
type: object
description: A JSONAPI-formatted error message.
properties:
errors:
type: array
items:
type: object
readOnly: true
required:
- id
- code
properties:
id:
type: string
readOnly: true
status:
type: string
readOnly: true
code:
type: string
readOnly: true
title:
type: string
readOnly: true
detail:
type: string
readOnly: true
source:
type: object
readOnly: true
properties:
pointer:
type: string
readOnly: true
header:
type: string
readOnly: true
parameter:
type: string
readOnly: true
UpdateSignalRequest:
type: object
description: Fields to update on a Signal. All fields are optional and only supplied fields are applied.
properties:
enabled:
type: boolean
description: Turn the Signal on (`true`) or off (`false`).
example: true
sensitivity:
allOf:
- $ref: '#/components/schemas/AnomalySignalSensitivity'
description: 'Set the sensitivity bucket for `error_rate` Signals. Cannot be set on `presence` Signals or on Signals that have not yet trained.
'
recipients:
type: array
description: 'Replace the Signal''s Recipient set with the given list. An empty array clears all Recipients. Each Recipient must be referenced by its `id` from the [Recipients API](/api/recipients/). Requires the **Manage Recipients** permission in addition to **Manage Signals**.
'
items:
$ref: '#/components/schemas/SignalRecipient'
NotificationRecipient:
type: object
properties:
id:
type: string
type:
deprecated: true
description: 'One of the allowed Recipient types.
Deprecated: Use the Recipients API first, then pass the Recipient ID.
'
allOf:
- $ref: '#/components/schemas/RecipientType'
target:
type: string
deprecated: true
description: 'The target of the notification. For example, the specific Slack channel or email address.
For Recipients of `type = "webhook"` or `type = "msteams_workflow"`,
this will be the Name in the UI and `webhook_name` in the Recipients API.
Deprecated: Use the Recipients API first, then pass the Recipient ID.
'
details:
$ref: '#/components/schemas/NotificationRecipientDetails'
SignalRecipient:
type: object
required:
- id
description: A Recipient assigned to a Signal.
properties:
id:
type: string
description: The unique identifier of an existing Recipient. Create Recipients via the [Recipients API](/api/recipients/).
example: hcar_01jak3ymk8s5cpc2xz3q7d8v9r
details:
type: object
description: Per-assignment settings for how this Recipient receives notifications for this Signal.
properties:
pagerduty_severity:
type: string
description: Severity to use when the assigned Recipient is a PagerDuty Recipient. Rejected for non-PagerDuty Recipients.
enum:
- critical
- error
- warning
- info
example: critical
muted:
type: boolean
description: When `true`, the Recipient is muted for this Signal and will not receive notifications.
default: false
DetailedError:
x-tags:
- Errors
description: An RFC7807 'Problem Detail' formatted error message.
type: object
required:
- error
- status
- type
- title
properties:
error:
type: string
readOnly: true
default: something went wrong!
status:
type: number
readOnly: true
description: The HTTP status code of the error.
type:
type: string
readOnly: true
description: Type is a URI used to uniquely identify the type of error.
title:
type: string
readOnly: true
description: Title is a human-readable summary that explains the `type` of the problem.
detail:
type: string
readOnly: true
description: The general, human-readable error message.
instance:
type: string
readOnly: true
description: The unique identifier (ID) for this specific error.
HistoricalAnomalyNormalRange:
type: object
description: The trained normal band a measurement exceeded.
required:
- lower
- upper
properties:
lower:
type: number
description: The lower bound of the trained normal band.
example: 0.01
upper:
type: number
description: The upper bound of the trained normal band.
example: 0.08
SignalDetailResponse:
description: A Signal with its assigned Recipients.
allOf:
- $ref: '#/components/schemas/Signal'
- type: object
required:
- recipients
properties:
recipients:
type: array
description: The Recipients notified when this Signal fires.
items:
$ref: '#/components/schemas/NotificationRecipient'
example:
- id: hcar_01jak3ymk8s5cpc2xz3q7d8v9r
type: pagerduty
details:
pagerduty_severity: critical
muted: false
ValidationError:
x-tags:
- Errors
allOf:
- $ref: '#/components/schemas/DetailedError'
- type: object
properties:
status:
type: number
readOnly: true
default: 422
type:
type: string
readOnly: true
default: https://api.honeycomb.io/problems/validation-failed
title:
type: string
readOnly: true
default: The provided input is invalid.
type_detail:
type: array
items:
type: object
properties:
field:
type: string
readOnly: true
code:
type: string
readOnly: true
enum:
- invalid
- missing
- incorrect_type
- already_exists
description:
type: string
readOnly: true
HistoricalAnomaly:
type: object
description: A resolved anomaly that a Signal previously fired for.
required:
- id
- started_at
- ended_at
- measurement
- normal_range
properties:
id:
type: string
description: A deterministic identifier for the anomaly, derived from the Signal, its measured kind, and the anomaly's start time.
readOnly: true
example: 0f8d0f3a-3f8b-5f2b-8f2b-1f2b3f4b5f6b
started_at:
type: integer
description: The time the anomaly started, in seconds since UNIX epoch.
readOnly: true
example: 1741089600
ended_at:
type: integer
description: The time the anomaly ended, in seconds since UNIX epoch.
readOnly: true
example: 1741093200
measurement:
type: number
description: The measured value that triggered the anomaly.
readOnly: true
example: 0.42
normal_range:
oneOf:
- $ref: '#/components/schemas/HistoricalAnomalyNormalRange'
- type: 'null'
description: The trained normal band the measurement exceeded. Always `null` for anomalies on `presence` Signals.
RecipientType:
type: string
description: One of the supported Recipient Types
enum:
- pagerduty
- email
- slack
- webhook
- msteams
- msteams_workflow
Signal:
type: object
description: A Honeycomb Anomaly Detection Signal.
required:
- id
- service_name
- dataset_slug
- environment_slug
- measured_signal
- enabled
- status
- sensitivity
- auto_investigate
- currently_anomalous
- last_anomaly_started_at
- last_anomaly_ended_at
- created_at
- updated_at
properties:
id:
type: string
description: Unique identifier (ID) of the Signal.
readOnly: true
example: hcasp_01j9x1yq0k2t8m9n3v4b5r6c7d
service_name:
type: string
description: The name of the service the Signal monitors.
readOnly: true
example: checkout-api
dataset_slug:
type: string
description: The slug of the dataset the Signal's service reports to.
readOnly: true
example: checkout-api
environment_slug:
type: string
description: The slug of the environment the Signal belongs to.
readOnly: true
example: production
measured_signal:
allOf:
- $ref: '#/components/schemas/AnomalySignal'
description: The kind of measurement the Signal is trained on.
readOnly: true
enabled:
type: boolean
description: Whether the Signal is currently enabled. Disabled Signals do not fire.
example: true
status:
allOf:
- $ref: '#/components/schemas/AnomalySignalStatus'
description: The lifecycle status of the Signal.
readOnly: true
sensitivity:
oneOf:
- $ref: '#/components/schemas/AnomalySignalSensitivity'
- type: 'null'
description: 'How far a measurement must deviate from the trained normal band before the Signal fires. Always `null` for `presence` Signals, and `null` for any Signal that has not yet trained.
'
auto_investigate:
type: boolean
description: When `true`, Honeycomb will automatically start an investigation when this Signal fires.
readOnly: true
example: false
currently_anomalous:
type: boolean
description: Whether the Signal is currently in an anomalous state.
readOnly: true
example: false
last_anomaly_started_at:
type:
- integer
- 'null'
description: The start time of the most recent anomaly, in seconds since UNIX epoch. `null` when the Signal has never been anomalous.
readOnly: true
example: 1741089600
last_anomaly_ended_at:
type:
- integer
- 'null'
description: The end time of the most recent anomaly, in seconds since UNIX epoch. `null` when no anomaly has ended yet, or the Signal is currently anomalous.
readOnly: true
example: 1741093200
created_at:
type: string
format: date-time
description: The ISO8601-formatted time when the Signal was created.
readOnly: true
example: '2025-02-14T17:32:11Z'
updated_at:
type: string
format: date-time
description: The ISO8601-formatted time when the Signal was last updated.
readOnly: true
example: '2025-03-01T10:04:22Z'
AnomalySignalStatus:
type: string
description: 'The lifecycle status of the Signal.
`ineligible` is returned when the underlying service does not meet the conditions
required for training.
'
enum:
- onboarding
- normal
- anomalous
- 'off'
- ineligible
example: normal
PaginatedHistoricalAnomaliesResponse:
type: object
description: A page of resolved historical anomalies for a Signal.
required:
- historical_anomalies
properties:
historical_anomalies:
type: array
description: The anomalies in this page, most recent first.
items:
$ref: '#/components/schemas/HistoricalAnomaly'
links:
$ref: '#/components/schemas/PaginationLinks'
AnomalySignalSensitivity:
type: string
description: 'How far a measurement must deviate from the trained normal band before the Signal fires.
Higher sensitivity narrows the normal band and catches smaller deviations.
`sensitivity` is always `null` for `presence` Signals.
'
enum:
- low
- medium
- high
example: medium
responses:
BadRequest:
description: The provided request body was invalid.
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/DetailedError'
examples:
DetailedError:
value:
status: 400
type: https://api.honeycomb.io/problems/unparseable
title: The request body could not be parsed.
error: invalid gzip data
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
GenericError:
value:
error: invalid Query data
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
examples:
JSONAPIError:
value:
errors:
- id: 06dcdd6508ca822f0e7e2bb4121c1f52
code: invalid
title: request body could not be parsed
detail: invalid gzip data
ValidationFailed:
description: Validation Failed
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ValidationError'
example:
status: 422
type: https://api.honeycomb.io/problems/validation-failed
error: The provided input is invalid.
title: The provided input is invalid
type_detail:
- field: type
code: invalid
description: 'type: must be a valid value'
application/json:
schema:
$ref: '#/components/schemas/Error'
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
Forbidden:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
deny-management-apis:
description: Team cannot access management APIs.
value:
error: Your team has been denied access to Management APIs, please contact support to be unblocked.
application/problem+json:
schema:
$ref: '#/components/schemas/DetailedError'
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: unknown API key - check your credentials
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
Conflict:
description: Conflict
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: dataset not found
application/problem+json:
schema:
$ref: '#/components/schemas/DetailedError'
example:
status: 409
type: https://api.honeycomb.io/problems/conflict
title: Request could not be completed due to a conflict with the current state of the target resource.
error: A resource by that name already exists.
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
RateLimited:
description: Rate Limit Exceeded
headers:
Retry-After:
$ref: '#/components/headers/RetryAfter'
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: Rate Limited
application/problem+json:
schema:
$ref: '#/components/schemas/DetailedError'
example:
status: 429
type: https://api.honeycomb.io/problems/rate-limited
title: You have exceeded your rate limit.
error: You have exceeded your rate limit.
detail: Please try again after 2025-02-01T15:23:12Z.
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
example:
errors:
- id: 06dcdd6508ca822f0e7e2bb4121c1f52
code: rate-limited/may-retry
title: request rate limit exceeded
detail: Please try again after 2025-02-01T15:23:12Z.
NotFound:
description: Not Found
headers:
Ratelimit:
$ref: '#/components/headers/RateLimit'
RateLimitPolicy:
$ref: '#/components/headers/RateLimitPolicy'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: dataset not found
application/problem+json:
schema:
$ref: '#/components/schemas/DetailedError'
example:
status: 404
type: https://api.honeycomb.io/problems/not-found
title: The requested resource cannot be found.
error: Dataset not found
detail: Dataset not found
application/vnd.api+json:
schema:
$ref: '#/components/schemas/JSONAPIError'
GenericError:
description: Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
headers:
RateLimitPolicy:
description: "The (draft07) recommended header from the IETF on rate limiting.\nThe value of the header is formatted \"X;w=Y\".\nWhere:\n - X is the maximum number of requests allowed in a window\n - Y is the size of the window in seconds\n"
schema:
type: string
example: 100;w=60
RateLimit:
description: "The (draft07) recommended header from the IETF on rate limiting.\nThe value of the header is formatted \"limit=X, remaining=Y, reset=Z\".\nWhere:\n - X is the maximum number of requests allowed in the window\n - Y is the number of requests remaining in the window\n - Z is the number of seconds until the limit resets\n"
schema:
type: string
example: limit=100, remaining=50, reset=60
RetryAfter:
description: 'The RFC7231 header used to indicate when a client should retry requests.
'
schema:
type: string
example: Fri, 22 Mar 2024 18:37:53 GMT
securitySchemes:
configuration_key:
type: apiKey
name: X-Honeycomb-Team
in: header
description: 'Authenticate using a Honeycomb Configuration Key.
Pass the **Token** in the `X-Honeycomb-Team` header:
```http
X-Honeycomb-Team: 1234567890123456789012
```
If you created your key using the API, use `data.attributes.secret`; this is the same value as the **Token** in the UI.
To learn how to create a Configuration Key, visit [Manage Environment API Keys](/configure/environments/manage-api-keys). To learn more about authenticating requests, visit [API Authentication](/api/authentication).
'
externalDocs:
url: https://docs.honeycomb.io