---
title: Update a fault
description: Updates a fault's attributes.
url: https://docs.honeybadger.io/api/v3/faults/update-fault/
---

API v3 is in preview

Endpoints and response shapes [can change before general availability](https://docs.honeybadger.io/api/v3/#preview). API v2 is unchanged.

PATCH `https://app.honeybadger.io/v3/projects/{project_id}/faults/{fault_id}`

[Required scope](https://docs.honeybadger.io/api/v3/authentication/#scopes) `faults:write`

Updates a fault’s attributes.

Example request

```sh
curl -X PATCH "https://app.honeybadger.io/v3/projects/$PROJECT_ID/faults/$FAULT_ID" \
  -H "Authorization: Bearer $HONEYBADGER_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "resolved": true
}'
```

## Parameters

### Path parameters

| Field | Type | Description |
| - | - | - |
| `project_id` required | string | Project ID. |
| `fault_id` required | string | Fault ID. |

## Request body

| Field | Type | Description |
| - | - | - |
| `resolved` | boolean | |
| `ignored` | boolean | |
| `assignee_id` | string \| null | ID of a user on the project. Null unassigns. |
| `tags` | array \| null | |
| `resolve_on_deploy` | boolean | Set to true to resolve this fault when the project's next deploy is recorded, in any environment. After that deploy, it reads false again. It has no effect if the fault is resolved or ignored once the rest of this update is applied. If the fault is resolved or ignored before the next deploy, the pending resolution is cancelled. Set it to false to cancel it yourself. |

## Responses

### 200 Success

Example payload

```json
{
  "data": {
    "id": "12345",
    "project_id": "Xk9mZp",
    "klass": "NoMethodError",
    "message": "undefined method 'foo' for nil:NilClass",
    "component": "UsersController",
    "action": "show",
    "environment": "production",
    "resolved": true,
    "ignored": true,
    "created_at": "2026-01-01T00:00:00Z",
    "last_notice_at": "2026-01-01T00:00:00Z",
    "notices_count": 214,
    "comments_count": 2,
    "tags": [
      "critical",
      "backend"
    ],
    "assignee_id": "Uq7rT2",
    "snoozed": true,
    "assignee": {
      "id": "Uz4wKm",
      "name": "Jane Smith",
      "email": "jane@example.com"
    },
    "last_notice_deploy": {
      "id": "Dp2yNk",
      "project_id": "Xk9mZp",
      "environment": "production",
      "revision": "a1b2c3d4",
      "repository": "acme/app",
      "local_username": "jane",
      "created_at": "2026-01-01T00:00:00Z"
    },
    "tickets": [
      {
        "url": "https://github.com/acme/shop/issues/482",
        "integration_id": "Ch9wLp"
      }
    ],
    "resolve_on_deploy": true,
    "recording_paused_until": "2026-01-01T00:00:00Z",
    "notices_count_in_range": 37,
    "links": {
      "web": "https://app.honeybadger.io/projects/Xk9mZp"
    }
  },
  "meta": {
    "request_id": "6f1c2b0e-8d4a-4f6e-9b2a-3c5d7e9f1a2b"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `data` required | object | A unique error fingerprint (fault). |
| `data.id` required | string | |
| `data.project_id` required | string | ID of the project this fault belongs to. |
| `data.klass` | string \| null | Error class name. |
| `data.message` required | string | Error message. |
| `data.component` | string \| null | Component where the error occurred. |
| `data.action` | string \| null | Action where the error occurred. |
| `data.environment` | string \| null | Environment name. |
| `data.resolved` | boolean | Whether the fault is resolved. |
| `data.ignored` | boolean | Whether the fault is ignored. |
| `data.created_at` required | date-time | When the fault was first reported. |
| `data.last_notice_at` | date-time \| null | When the last notice was received. |
| `data.notices_count` | integer | Total number of notices for this fault. |
| `data.comments_count` | integer | Number of comments on this fault. |
| `data.tags` | array\<string> | Tags assigned to this fault. |
| `data.assignee_id` | string \| null | Same as `assignee.id`. Written by PATCH or POST …/assign. |
| `data.snoozed` | boolean | Whether a snooze is in effect now. A new snooze replaces any existing one. |
| `data.assignee` | object \| null | User assigned to this fault. |
| `data.assignee.id` | string | ID of the assignee. |
| `data.assignee.name` | string \| null | Name of the assignee. |
| `data.assignee.email` | string | Email of the assignee. |
| `data.last_notice_deploy` | object \| null | The deploy that was live when the error last occurred: the newest deploy in the fault's environment before `last_notice_at`. A guess from timing, not the deploy that introduced or resolved the error. |
| `data.last_notice_deploy.id` required | string | |
| `data.last_notice_deploy.project_id` required | string | ID of the project this deploy belongs to. |
| `data.last_notice_deploy.environment` required | string \| null | Deploy environment; null when the deploy named none. |
| `data.last_notice_deploy.revision` required | string \| null | Source control revision. |
| `data.last_notice_deploy.repository` required | string \| null | Source control repository. |
| `data.last_notice_deploy.local_username` required | string \| null | Username of the person who triggered the deploy. |
| `data.last_notice_deploy.created_at` required | date-time | When the deploy was recorded. |
| `data.tickets` | array\<object> | Issue tracker tickets linked to this fault. |
| `data.tickets[].url` | string | URL of the ticket. |
| `data.tickets[].integration_id` | string | ID of the integration that created the ticket. |
| `data.resolve_on_deploy` | boolean | Whether this fault is waiting to be resolved by the next recorded deploy. Absent for a fault on an inactive project. |
| `data.recording_paused_until` | date-time \| null | When a recording pause ends; null when recording is not paused. Absent for a fault on an inactive project. |
| `data.notices_count_in_range` | integer | Notices inside the requested occurrence window. Present only when the request supplied `occurred_after` or `occurred_before`. |
| `data.links` required | object | Links into the Honeybadger web UI. |
| `data.links.web` required | uri | The 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique identifier for the request, for correlating with support. |

## Errors

### 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)

```json
{
  "error": {
    "code": "unauthorized",
    "message": "Access denied"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Example payload: unsupported\_auth\_scheme (Sent as HTTP basic, which v3 does not accept)

```json
{
  "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)

```json
{
  "error": {
    "code": "credential_in_query",
    "message": "Credentials must be sent in the Authorization header"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `error` required | object | |
| `error.code` required | string | Machine-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` required | string | Human-readable explanation. |
| `error.details` | array\<object> \| object | A 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique 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)

```json
{
  "error": {
    "code": "access_denied",
    "message": "Access denied"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Example payload: insufficient\_scope (The credential lacks the permission this endpoint requires)

```json
{
  "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)

```json
{
  "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)

```json
{
  "error": {
    "code": "project_restricted",
    "message": "Project-restricted tokens cannot create projects"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `error` required | object | |
| `error.code` required | string | Machine-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` required | string | Human-readable explanation. |
| `error.details` | array\<object> \| object | A 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique identifier for the request, for correlating with support. |

### 404 Not Found

Resource not found

Example payload

```json
{
  "error": {
    "code": "not_found",
    "message": "Resource not found"
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `error` required | object | |
| `error.code` required | string | Machine-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` required | string | Human-readable explanation. |
| `error.details` | array\<object> \| object | A 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique identifier for the request, for correlating with support. |

### 409 Conflict

This fault was merged into another, so the write wasn’t applied. `error.details` names the fault it was merged into.

Example payload

```json
{
  "error": {
    "code": "fault_merged",
    "message": "This fault was merged into fault 12345",
    "details": {
      "merged_into": "12345",
      "location": "https://app.honeybadger.io/v3/projects/Xk9mZp/faults/12345"
    }
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `error` required | object | |
| `error.code` required | string | Machine-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` required | string | Human-readable explanation. |
| `error.details` | array\<object> \| object | A 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique identifier for the request, for correlating with support. |

### 422 Unprocessable Content

Validation error

Example payload

```json
{
  "error": {
    "code": "validation_error",
    "message": "Name can't be blank",
    "details": [
      {
        "field": "name",
        "message": "can't be blank"
      }
    ]
  },
  "meta": {
    "request_id": "abc123"
  }
}
```

Response schema

| Field | Type | Description |
| - | - | - |
| `error` required | object | |
| `error.code` required | string | Machine-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` required | string | Human-readable explanation. |
| `error.details` | array\<object> \| object | A 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. |
| `meta` | object | |
| `meta.request_id` | string | Unique identifier for the request, for correlating with support. |

---

## Try Honeybadger for FREE

Intelligent logging, error tracking, and Just Enough APM™ in one dev-friendly platform. Find and fix problems before users notice.

[Start free trial](https://app.honeybadger.io/users/sign_up)

[See plans and pricing](https://www.honeybadger.io/plans/)
