> ## Documentation Index
> Fetch the complete documentation index at: https://www.openpmm.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Use OpenPMM error codes and request IDs to diagnose failed API requests.

OpenPMM returns an RFC 9457 problem response for an API error. The response has the `application/problem+json` media type. Use the HTTP status for the error class. Use `code` for application logic.

```json theme={null}
{
  "type": "https://www.openpmm.com/docs/reference/errors#public_invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "The request body does not match the public contract.",
  "instance": "urn:openpmm:request:req_01JABCDEF",
  "code": "public_invalid_request",
  "category": "validation",
  "request_id": "req_01JABCDEF",
  "retryable": false,
  "retry": {"safety": "not_retryable", "after": null},
  "user_action": "check_request",
  "errors": [
    {
      "pointer": "/posts/0/destination_id",
      "code": "custom",
      "detail": "Publishing an entry requires a destination."
    }
  ]
}
```

## Problem fields

A problem response always has these fields.

| Field         | Description                                                             |
| ------------- | ----------------------------------------------------------------------- |
| `type`        | The Errors page URI with the error code as its fragment                 |
| `title`       | A short summary of the failure                                          |
| `status`      | The HTTP status                                                         |
| `detail`      | An explanation of this failure                                          |
| `instance`    | The request URN with the format `urn:openpmm:request:{request_id}`      |
| `code`        | The stable error code. Use this value in application logic              |
| `category`    | The stable error category                                               |
| `request_id`  | The identifier of the request                                           |
| `retryable`   | `true` when you can send the same request again                         |
| `retry`       | The retry safety and optional delay                                     |
| `user_action` | The next action for a person or agent                                   |
| `errors`      | The list of field errors. The list is empty when no field error applies |

Some `429` responses also include `reason` and `retry_at`. Use `reason` to
distinguish a request-rate limit from a publishing-safety limit. Use `retry_at`
when it is present.

Each item in `errors` has a `code` and a `detail`. An item that refers to a
member of the request also has a `pointer`. The `pointer` value is a JSON
Pointer to that member.

Destination-specific Post errors can occur during Create Post or Publish Post.
They use `publisher_validation_failed` with HTTP status `422`. For example, a
missing Instagram `destination_options` object points to `/posts/0/destination_options`. These errors
are not retryable until you correct the request.

`x_character_limit_exceeded` is the top-level problem code when an X body item
exceeds the selected Destination limit.
The detail includes the effective weighted-character limit.
Shorten the item and retry.
Refresh the Destination after the X account subscription changes.

## What to log

Log the HTTP status, `code`, and `request_id`. Do not log API keys, provider credentials, or post content.

## Retry guidance

Read `retryable` first. A `false` value tells you to correct the request before
you send it again. The table gives the typical action for each status.

| Status         | Typical action                                                                                                                    |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `400` or `422` | Correct the request before you retry                                                                                              |
| `401`          | Correct or replace the API key                                                                                                    |
| `402`          | Start or correct the subscription. End the trial before you use X.                                                                |
| `403`          | Check the credential scopes and workspace access                                                                                  |
| `404`          | Check the resource ID and workspace ID                                                                                            |
| `409`          | Check the resource state or idempotency key                                                                                       |
| `412`          | Get the resource again and use its current ETag                                                                                   |
| `429`          | Read `code` and `reason`. Use `Retry-After` or `retry_at` when present. For `reason: backlog`, wait for existing posts to finish. |
| `5xx`          | Retry with a delay and the same idempotency key                                                                                   |

### CLI browser authorization

| Code                          | Status | Action                                                                                                                                           |
| ----------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `cli_authorization_not_found` | `404`  | Start a new browser authorization. The request may be missing or expired.                                                                        |
| `cli_authorization_denied`    | `403`  | Ask the user before starting a new authorization.                                                                                                |
| `cli_authorization_consumed`  | `409`  | Do not exchange the request again. Use the credential already stored by the successful CLI process, or start a new authorization if it was lost. |

<Warning>
  A network timeout or provider error can occur after publication. Get the post status before you create a new post.
</Warning>

## Request limits and publishing safety

OpenPMM applies separate controls to HTTP requests and provider work.

| Control                    | Stable code                    | What it protects                                                  | Action                                         |
| -------------------------- | ------------------------------ | ----------------------------------------------------------------- | ---------------------------------------------- |
| Public API request limit   | `public_rate_limited`          | The authenticated `/v1` API                                       | Wait for `Retry-After`                         |
| X monthly allowance        | `x_usage_limit_reached`        | The 50 X post items for one Workspace and UTC month               | Wait for the next UTC month                    |
| Publishing admission limit | `publishing_admission_limited` | The amount of new provider work for an Account                    | Read `reason`. Wait when `retry_at` is present |
| Account publishing pause   | `publishing_account_paused`    | Shared publishing infrastructure after repeated safety violations | Wait until `retry_at`                          |

The `RateLimit` and `RateLimit-Policy` headers describe HTTP request allowance.
They do not describe provider capacity or publishing units. Header items use
neutral identifiers such as `requests`, `minute`, and `sustained`, followed by
the numeric request limit and window. These identifiers are not provider names,
product policy names, or versions.

A publishing admission response rejects the complete new submission before
OpenPMM stores a Post. The `reason` is `velocity`, `backlog`, or
`account-paused`.

`public_idempotency_outcome_unknown` means that the earlier mutation can have
completed. The CLI uses exit `9` for this response. Inspect the affected Posts
or other resources before you create new work.

Provider publishing limits apply to one destination. A Post can fail with
`provider_publishing_limit` and automatic retry is disabled. Other destination
Posts continue. Use a confirmed manual retry later.
