---
title: "Ответ на запросы к серверному API: 400: Bad request"
description: ""
---

### billing_issue_detected_at_date_comparison_error

Проблема с оплатой возникает при неудачной попытке продления подписки, поэтому она всегда происходит после даты транзакции (`purchased_at`).

Убедитесь, что дата проблемы с оплатой (`billing_issue_detected_at`) позже даты транзакции (`purchased_at`).

#### Тело ответа \{#body\}

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `billing_issue_detected_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `billing_issue_detected_at_date_comparison_error`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа \{#response-example\}

```json showLineNumbers
{
  "errors": [
    {
      "source": "billing_issue_detected_at",
      "errors": [
        "billing_issue_detected_at must be later than purchased_at."
      ]
    }
  ],
  "error_code": "billing_issue_detected_at_date_comparison_error",
  "status_code": 400
}
```

---

### expires_date_error

Пользователь не может купить подписку, которая уже истекла. Поэтому дата `expires_at` (когда истекает подписка) всегда должна быть позже даты `purchased_at` (когда произошла транзакция).

Чтобы исправить ошибку, проверьте эти даты и убедитесь, что `expires_at` позже `purchased_at`.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `expires_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `expires_date_error`.        |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "expires_at",
      "errors": [
        "expires_at must be later than purchased_at."
      ]
    }
  ],
  "error_code": "expires_date_error",
  "status_code": 400
}
```

---

### family_share_price_error

Запрос завершился ошибкой, потому что параметр `is_family_shared` установлен в `true`, то есть уровень доступа предоставляется члену семьи бесплатно. При этом параметр `value` объекта [Price](server-side-api-objects#price) не равен нулю.

Если `is_family_shared` должен быть `true`, убедитесь, что параметр `value` объекта [Price](server-side-api-objects#price) установлен в `0`.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `is_family_shared`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Короткое название ошибки. Всегда: `family_share_price_error`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

Профиль не найден

```json showLineNumbers
{
  "errors": [
    {
      "source": "is_family_shared",
      "errors": [
        "If is_family_shared is true, price.value must be 0."
      ]
    }
  ],
  "error_code": "family_share_price_error",
  "status_code": 400
}
```

---

### free_trial_price_error

Запрос завершился ошибкой, поскольку параметр `offer_type` имеет значение `free_trial`, но параметр `value` объекта [Price](server-side-api-objects#price) не равен нулю.

Ещё одна возможная причина: параметр `offer_id` был указан, но оставлен `null`, хотя он не может быть null. В этом случае либо укажите значение для `offer_id`, либо удалите параметр полностью.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `offer.type`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда: `free_trial_price_error`.   |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

Профиль не найден

```json showLineNumbers
{
  "errors": [
    {
      "source": "offer_type",
      "errors": [
        "If offer_type is 'free_trial', price.value must be 0."
      ]
    }
  ],
  "error_code": "free_trial_price_error",
  "status_code": 400
}
```

---

### grace_period_expires_date_error

Льготный период — это дополнительное время, которое вы можете дать пользователям для продления подписки, если они не успели это сделать вовремя, например из-за проблем с оплатой картой. Это позволяет сохранить их настройки, пока они разбираются с ситуацией. Предоставлять льготный период необязательно.

Если льготный период предусмотрен, дата его окончания (`grace_period_expires_at`) должна быть позже даты окончания подписки (`expires_at`). В противном случае время окончания льготного периода совпадёт со временем окончания подписки. В любом случае льготный период не может истекать раньше, чем подписка.

Чтобы исправить ошибку, убедитесь, что дата окончания льготного периода (`grace_period_expires_at`) позже даты окончания подписки (`expires_at`).

#### Body

| Parameter   | Type    | Description                                                  |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `grace_period_expires_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `grace_period_expires_date_error`.  |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа \{#response-example\}

```json showLineNumbers
{
  "errors": [
    {
      "source": "grace_period_expires_at",
      "errors": [
        "grace_period_expires_at must be later or equal to expires_at."
      ]
    }
  ],
  "error_code": "grace_period_expires_date_error",
  "status_code": 400
}
```

---

### grace_period_billing_error

Начало льготного периода считается проблемой с выставлением счёта. Поэтому если льготный период начался (на это указывает заполненный параметр `grace_period_expires_at`), его дата начала должна быть записана в параметр `billing_issue_detected_at`.

Чтобы исправить ошибку, либо укажите дату начала льготного периода в `billing_issue_detected_at`, либо, если льготный период ещё не начался, удалите параметр `grace_period_expires_at`.

#### Body

| Parameter   | Type    | Description                                                  |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `grace_period_billing_error`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `grace_period_billing_error`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа \{#response-example\}

```json showLineNumbers
{
  "errors": [
    {
      "source": "grace_period_billing_error",
      "errors": [
        "If grace_period_expires_at is specified, billing_issue_detected_at must also be specified."
      ]
    }
  ],
  "error_code": "grace_period_billing_error",
  "status_code": 400
}
```

---

### missing_offer_id

Запрос завершился ошибкой, потому что параметр `offer_category` имеет значение, отличное от `introductory` или `offer_type`, но при этом не содержит `offer_id`. В таком случае нужно либо указать `offer_id`, либо убрать `offer_category` или `offer_type` из запроса.

Другая возможная причина: параметр `offer_id` добавлен, но задан как `null`, хотя он не может быть `null`. В этом случае нужно либо указать значение для `offer_id`, либо полностью убрать этот параметр.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `offer.category`</li><li> **errors**: Описание ошибки. </li></ul> |
| error_code  | String  | Короткое название ошибки. Возможное значение: `missing_offer_id`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

Профиль не найден

```json showLineNumbers
{
  "errors": [
    {
      "source": "offer_category",
      "errors": [
        "offer_id must be specified for all offer types except 'introductory'."
      ]
    }
  ],
  "error_code": "missing_offer_id",
  "status_code": 400
}
```

---

### one_time_purchase_trial_error

Запрос завершился ошибкой, так как к разовой покупке был привязан пробный период. В отличие от подписок, разовые покупки не поддерживают пробный период. Чтобы исправить это, проверьте значение `offer_type` в объекте [Offer](server-side-api-objects#offer) внутри объекта [One-Time Purchase](server-side-api-objects#one-time-purchase). Значение `offer_type` не может быть `free_trial`. Измените значение поля `offer_type` или используйте объект [Subscription](server-side-api-objects#subscription) вместо One-Time Purchase.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда offer.type</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `one_time_purchase_trial_error`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "offer.type",
      "errors": [
        "One-time purchase cannot have a trial."
      ]
    }
  ],
  "error_code": "one_time_purchase_trial_error",
  "status_code": 400
}
```

---

### originally_purchased_date_error

Для продлённых подписок формируется цепочка транзакций. Первая транзакция в этой цепочке называется исходной и связывает все последующие. Каждое продление является расширением этой исходной транзакции. Если транзакция является первой покупкой, она сама выступает своей исходной транзакцией.

Временная метка `originally_purchased_at` фиксирует момент исходной покупки, а `purchased_at` — момент текущей транзакции. Поэтому `purchased_at` никогда не может быть раньше `originally_purchased_at`; в крайнем случае они совпадают — для самой первой транзакции.

Запрос завершился с ошибкой, потому что `originally_purchased_at` указан позже, чем `purchased_at`. Убедитесь, что это значение меньше или равно `purchased_at`.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `originally_purchased_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `originally_purchased_date_error`.  |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "originally_purchased_at",
      "errors": [
        "originally_purchased_at must be earlier than or equal to purchased_at."
      ]
    }
  ],
  "error_code": "originally_purchased_date_error",
  "status_code": 400
}
```

---

### paid_access_level_does_not_exist

Запрос завершился ошибкой, потому что указанный в запросе уровень доступа не найден. Проверьте, нет ли опечаток в `access_level_id`, и убедитесь, что он соответствует нужному приложению.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `non_field_errors`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Возможное значение: `paid_access_level_does_not_exist`. |
| status_code | Integer | HTTP-статус. Всегда `404`.                                   |

#### Пример ответа

Уровень доступа не найден.

```json showLineNumbers
{
  "errors": [
    {
      "source": "non_field_errors",
      "errors": [
        "Paid access level `premium` does not exist"
      ]
    }
  ],
  "error_code": "paid_access_level_does_not_exist",
  "status_code": 400
}
```

---

### profile_does_not_exist

<p> </p>

Запрос завершился ошибкой, потому что профиль из заголовка запроса не найден. Проверьте, нет ли опечаток в `profile_id` или `customer_user_id`, указанных в заголовке запроса, и убедитесь, что они относятся к правильному приложению.

#### Тело

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `non_field_errors`</li><li> **errors**: Описание ошибки. </li></ul> |
| error_code  | String  | Краткое название ошибки. Возможное значение: `profile_does_not_exist`.  |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

Профиль не найден

```json showLineNumbers
{
  "errors": [
    {
      "source": "non_field_errors",
      "errors": [
        "Profile not found"
      ]
    }
  ],
  "error_code": "profile_does_not_exist",
  "status_code": 400
}
``` 

---

### profile_paid_access_level_does_not_exist

Запрос завершился с ошибкой, потому что профиль в запросе не соответствует указанному уровню доступа. Убедитесь, что ID профиля в заголовке и ID уровня доступа в теле запроса указаны верно, и проверьте наличие опечаток.

#### Тело ответа

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `non_field_errors`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `profile_paid_access_level_does_not_exist`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "non_field_errors",
      "errors": [
        "Profile `478b2e7f-d557-4b8b-9c5f-cbd46fc2dee2` has no `premium` access level"
      ]
    }
  ],
  "error_code": "profile_paid_access_level_does_not_exist",
  "status_code": 400
}
```

---

### refund_date_error

Запрос завершился с ошибкой, поскольку дата покупки (`purchased_at`) оказалась раньше или равна дате возврата (`refunded_at`). Возврат всегда происходит после покупки, так как является её отменой.

Чтобы исправить ошибку, проверьте параметры `purchased_at` и `refunded_at` и убедитесь, что дата возврата позже даты покупки.

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `refunded_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `refund_date_error`.         |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "refunded_at",
      "errors": [
        "refunded_at must be later than purchased_at."
      ]
    }
  ],
  "error_code": "refund_date_error",
  "status_code": 400
}
```

---

### refund_fields_error

Запрос завершился ошибкой, поскольку в нём указан `cancellation_reason` без даты `refunded_at`, либо `refunded_at` без `cancellation_reason`.

При установке возврата средств необходимо указать и дату, и причину возврата.

#### Тело ответа

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `refunded_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `refund_fields_error`.       |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "refunded_at",
      "errors": [
        "refunded_at and cancellation_reason=refund must be specified together."
      ]
    }
  ],
  "error_code": "refund_fields_error",
  "status_code": 400
}
```

---

### renew_status_changed_date_error

Продление — это пролонгация подписки. Пользователь может отменить автопродление, а затем снова включить его. Время обоих этих действий сохраняется в параметре `renew_status_changed_at` и не может быть раньше самой транзакции.

Чтобы исправить ошибку, убедитесь, что `renew_status_changed_at` позже времени транзакции (`purchased_at`).

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `originally_purchased_at`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Короткое название ошибки. Всегда `originally_purchased_date_error`.  |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
{
  "errors": [
    {
      "source": "renew_status_changed_at",
      "errors": [
        "renew_status_changed_at must be later than purchased_at."
      ]
    }
  ],
  "error_code": "renew_status_changed_date_error",
  "status_code": 400
}
```

---

### revocation_date_more_than_expiration_date

Запрос завершился ошибкой, потому что указанный в запросе параметр `revoke_at` позже текущего значения `expires_at` для данного уровня доступа. Если вы хотите продлить уровень доступа, используйте запрос [Предоставление уровня доступа](ss-grant-access-level).

#### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `non_field_errors`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Короткое название ошибки. Всегда `revocation_date_more_than_expiration_date`. |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

#### Пример ответа

```json showLineNumbers
  {
  "errors": [
    {
      "source": "revoke_at",
      "errors": [
        "Revocation date (2029-08-29 09:33:42+00:00) is more than current expiration date (2028-08-29 09:33:42+00:00)"
      ]
    }
  ],
  "error_code": "revocation_date_more_than_expiration_date",
  "status_code": 400
}
```

---

### store_transaction_id_error

В случае продлевающихся подписок формируется цепочка транзакций. Исходная транзакция — это самая первая транзакция в этой цепочке, и все остальные транзакции связаны через неё. Остальные транзакции в цепочке являются продлениями. Если транзакция является самой первой покупкой в цепочке подписок, она может быть своей собственной исходной транзакцией.

Другой случай — разовая покупка. Она никогда не создаёт цепочек, так как не может иметь продлений. Для неё `store_transaction_id` всегда совпадает с `store_original_transaction_id`.

Ваш запрос завершился с ошибкой, потому что значение `store_transaction_id` объекта [Разовая покупка](server-side-api-objects#one-time-purchase) отличается от его `store_original_transaction_id`. Чтобы исправить это, либо сделайте их одинаковыми, либо измените объект — используйте [Подписку](server-side-api-objects#subscription) вместо [Разовой покупки](server-side-api-objects#one-time-purchase).

#### Тело \{#body\}

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `store_transaction_id`</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `store_transaction_id_error`. |
| status_code | Integer | HTTP-статус. Всегда `400.`                                   |

#### Пример ответа \{#response-example\}

```json showLineNumbers
{
  "errors": [
    {
      "source": "store_transaction_id",
      "errors": [
        "store_transaction_id must be equal to store_original_transaction_id for purchase."
      ]
    }
  ],
  "error_code": "store_transaction_id_error",
  "status_code": 400
}
```

#### value_error

Запрос завершился ошибкой, поскольку указанная дата отзыва находится в прошлом. Установите `revoke_at` на будущую дату или передайте `null`, чтобы немедленно отозвать доступ.

##### Body

| Параметр    | Тип     | Описание                                                     |
| ----------- | ------- | ------------------------------------------------------------ |
| errors      | Object  | <ul><li> **source**: (string) Всегда `revoke_at`.</li><li> **errors**: Описание ошибки.</li></ul> |
| error_code  | String  | Краткое название ошибки. Всегда `value_error`.               |
| status_code | Integer | HTTP-статус. Всегда `400`.                                   |

##### Пример ответа

```json showLineNumbers
{
    "errors": [
        {
            "source": null,
            "errors": [
                "Must be greater than the current time or null"
            ]
        }
    ],
    "error_code": "value_error",
    "status_code": 400
}
```