Skip to content

Create a site

View Markdown
POST https://app.honeybadger.io/v3/projects/{project_id}/sites
Required scope uptime:write

Creates an uptime monitoring site. Requires uptime monitoring on the plan.

Example request
Terminal window
curl -X POST "https://app.honeybadger.io/v3/projects/$PROJECT_ID/sites" \
-H "Authorization: Bearer $HONEYBADGER_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.example.com/health"
}'

Parameters

1

Path parameters

FieldTypeDescription
project_id requiredstringProject ID.

Request body

name defaults to the URL.

FieldTypeDescription
namestringName shown for the site in Honeybadger and on status pages.
url requireduriMust start with http:// or https://, with no surrounding whitespace.
match_typestring | nullHow a check decides the site is up (see SiteMatchType). Null resets it to success. How a response is judged. success: any 2xx; match must be left out. exact: the response status code equals match. include / exclude: the body does / doesn't contain match. jmespath: match is a JMESPath expression evaluated against the JSON body; numbers in it use backticks, not quotes. Allowed values: success, exact, include, exclude, jmespath. Default: "success".
matchstring | nullWhat match_type compares against (see SiteMatchType). Required unless match_type is success, and must be left out with success. Null clears it. Max length 255.
request_methodstring | nullHTTP method each check sends. Null resets it to GET. Allowed values: GET, POST, PUT, PATCH, DELETE. Default: "GET".
validate_sslboolean | nullFail the check when the TLS certificate does not validate. Null resets it to true. Default: true.
request_bodystring | nullBody to send with the request, up to 32 KB. Null clears it. Max length 32768.
request_headersobject | nullHeaders to send with the request, as header name to value. Replaces the stored headers; null or {} clears them. Default: {}.
request_headers.*stringAny other keys.
frequencyinteger | nullMinutes between checks. The plan sets the most frequent allowed. Null resets it to 5. A value below the plan's floor is refused. Allowed values: 1, 2, 5, 15. Default: 5.
locationsarray | nullA set of location names to check from. Null or empty means every location. A set; order is ignored and duplicates are dropped. Allowed values: Virginia, Frankfurt, Singapore, London, Oregon. Default: [].
outage_thresholdinteger | nullConsecutive failures before an outage is declared. null means down once failures reach 50% of locations. Min 1.
activeboolean | nullWhether monitoring is active. After 740 consecutive failed checks the server sets it to false. Null resets it to true. Default: true.
timeoutinteger | nullRequest timeout in seconds, 1 to 120, default 30, and less than the frequency in seconds. Changing it requires the uptime timeout feature on the account; without it, only the current value (on create, the default) is accepted. Null resets it to the default.

Responses

1

201 Site created

Example payload
{
"data": {
"id": "9f8b6d2e-4c1a-4b7f-9e35-2a6c8d0f1b47",
"project_id": "Xk9mZp",
"name": "Production App",
"url": "https://app.example.com",
"active": true,
"state": "up",
"last_checked_at": "2026-01-01T00:00:00Z",
"match_type": "success",
"match": null,
"request_method": "GET",
"frequency": 1,
"locations": [
"Virginia",
"London"
],
"validate_ssl": true,
"request_headers": {},
"request_body": null,
"outage_threshold": 2,
"timeout": 30,
"created_at": "2026-01-01T00:00:00Z",
"links": {
"web": "https://app.honeybadger.io/projects/Xk9mZp"
}
},
"meta": {
"request_id": "6f1c2b0e-8d4a-4f6e-9b2a-3c5d7e9f1a2b"
}
}
Response schema24
FieldTypeDescription
data requiredobjectA URL Honeybadger checks for uptime from several locations on a schedule, alerting when it goes down and when it recovers.
data.id requireduuid
data.project_id requiredstringID of the project this site belongs to.
data.name requiredstringDisplay name for the site.
data.url requiredstringURL to monitor. Includes the scheme.
data.active requiredbooleanWhether monitoring is active. After 740 consecutive failed checks the server sets it to false.
data.state requiredstringCurrent state of the site. Allowed values: pending, up, down.
data.last_checked_at requireddate-time | nullWhen the site was last checked.
data.match_type requiredstringHow a response is judged. success: any 2xx; match must be left out. exact: the response status code equals match. include / exclude: the body does / doesn't contain match. jmespath: match is a JMESPath expression evaluated against the JSON body; numbers in it use backticks, not quotes. Allowed values: success, exact, include, exclude, jmespath.
data.match requiredstring | nullValue to match in the response.
data.request_method requiredstringAllowed values: GET, POST, PUT, PATCH, DELETE.
data.frequency requiredintegerMinutes between checks. A value below the plan's floor is refused. Allowed values: 1, 2, 5, 15.
data.locations requiredarray<string>Locations checks run from. Unordered. [] means every location. Allowed values: Virginia, Frankfurt, Singapore, London, Oregon.
data.validate_ssl requiredbooleanWhether to validate SSL certificates.
data.request_headers requiredobjectCustom headers sent with check requests, as header name to value; {} when there are none.
data.request_headers.*stringAny other keys.
data.request_body requiredstring | nullRequest body for POST/PUT checks.
data.outage_threshold requiredinteger | nullNumber of failed checks before declaring an outage.
data.timeout requiredinteger | nullThe stored request timeout in seconds; null means the default, 30. On a plan without custom timeouts the default applies whatever is stored.
data.created_at requireddate-timeWhen the site was created.
data.links requiredobjectLinks into the Honeybadger web UI.
data.links.web requireduriThe resource's page in the Honeybadger web UI, as an absolute URL. Resources without a page, such as outages and deploys, don't have links. For a project provisioned through Heroku, error, notice and comment links go through Heroku's single sign-on.
metaobject
meta.request_idstringUnique identifier for the request, for correlating with support.

Errors

4

401 Unauthorized

The credential is missing, invalid, expired or revoked (unauthorized), or was sent in a way v3 doesn’t accept (see the examples).

Example payload: unauthorized (Missing, malformed, expired or revoked credential)
{
"error": {
"code": "unauthorized",
"message": "Access denied"
},
"meta": {
"request_id": "abc123"
}
}
Example payload: unsupported_auth_scheme (Sent as HTTP basic, which v3 does not accept)
{
"error": {
"code": "unsupported_auth_scheme",
"message": "Send the credential as `Authorization: Bearer <token>`; v3 does not accept HTTP basic"
},
"meta": {
"request_id": "abc123"
}
}
Example payload: credential_in_query (Sent as the `auth_token` query parameter)
{
"error": {
"code": "credential_in_query",
"message": "Credentials must be sent in the Authorization header"
},
"meta": {
"request_id": "abc123"
}
}
Response schema6
FieldTypeDescription
error requiredobject
error.code requiredstringMachine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged.
error.message requiredstringHuman-readable explanation.
error.detailsarray<object> | objectA list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add.
metaobject
meta.request_idstringUnique identifier for the request, for correlating with support.

403 Forbidden

The credential isn’t allowed to do this. error.code says why. An account or project the credential doesn’t cover is 404 not_found, not 403.

Example payload: access_denied (The credential isn't allowed to do this to this record)
{
"error": {
"code": "access_denied",
"message": "Access denied"
},
"meta": {
"request_id": "abc123"
}
}
Example payload: insufficient_scope (The credential lacks the permission this endpoint requires)
{
"error": {
"code": "insufficient_scope",
"message": "Insufficient scope",
"details": {
"required_scope": "faults:write",
"token_scopes": [
"faults:read",
"insights:read"
]
}
},
"meta": {
"request_id": "abc123"
}
}
Example payload: requires_user_token (The endpoint records who acted, and an account token has nobody)
{
"error": {
"code": "requires_user_token",
"message": "This endpoint records the person who acted, so it requires a user credential rather than an account token"
},
"meta": {
"request_id": "abc123"
}
}
Example payload: project_restricted (A project-restricted credential cannot create a project)
{
"error": {
"code": "project_restricted",
"message": "Project-restricted tokens cannot create projects"
},
"meta": {
"request_id": "abc123"
}
}
Response schema6
FieldTypeDescription
error requiredobject
error.code requiredstringMachine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged.
error.message requiredstringHuman-readable explanation.
error.detailsarray<object> | objectA list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add.
metaobject
meta.request_idstringUnique identifier for the request, for correlating with support.

404 Not Found

Resource not found

Example payload
{
"error": {
"code": "not_found",
"message": "Resource not found"
},
"meta": {
"request_id": "abc123"
}
}
Response schema6
FieldTypeDescription
error requiredobject
error.code requiredstringMachine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged.
error.message requiredstringHuman-readable explanation.
error.detailsarray<object> | objectA list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add.
metaobject
meta.request_idstringUnique identifier for the request, for correlating with support.

422 Unprocessable Content

Validation error

Example payload
{
"error": {
"code": "validation_error",
"message": "Name can't be blank",
"details": [
{
"field": "name",
"message": "can't be blank"
}
]
},
"meta": {
"request_id": "abc123"
}
}
Response schema6
FieldTypeDescription
error requiredobject
error.code requiredstringMachine-readable code. Branch on this, not the message. Allowed values: unauthorized, unsupported_auth_scheme, credential_in_query, access_denied, insufficient_scope, requires_user_token, project_restricted, account_inactive, account_parked, feature_unavailable, not_found, validation_error, delete_failed, limit_reached, rate_limit_exceeded, concurrent_request, streams_provisioning, ingestion_key_not_accepted, maintenance_mode, invalid_parameter, forbidden_attributes, service_unavailable, ambiguous_account, fault_merged.
error.message requiredstringHuman-readable explanation.
error.detailsarray<object> | objectA list of {field, message} on validation_error and invalid_parameter, and on feature_unavailable or limit_reached when one field caused the refusal; {required_scope, token_scopes} on insufficient_scope; {merged_into, location} on fault_merged. Absent when there's nothing to add.
metaobject
meta.request_idstringUnique identifier for the request, for correlating with support.