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

# Downgrade Service

> Submit a service plan downgrade for background processing.

Submit a downgrade from the current service plan to a lower plan.

<Note>
  A successful response means that the API accepted the request. It does not mean that the plan change is complete.
</Note>

## Allowed Plan Changes

A downgrade must move from a higher plan to a lower plan in this order:

1. `Dedicated Server`
2. `Professional VPS`
3. `Standard VPS`
4. `Basic VPS`

| Current plan       | Allowed target plans                               |
| ------------------ | -------------------------------------------------- |
| `Dedicated Server` | `Professional VPS`, `Standard VPS`, or `Basic VPS` |
| `Professional VPS` | `Standard VPS` or `Basic VPS`                      |
| `Standard VPS`     | `Basic VPS`                                        |
| `Basic VPS`        | None                                               |

The endpoint rejects a request for the current plan. It also rejects a move to a higher plan. Use the [Upgrade Service](/api/services/upgrade) endpoint for a move to a higher plan.

## Accepted Response

The endpoint returns HTTP `200` after it queues the work.

The response does not contain an internal request UUID, an action ID, or a completion time.

## Downgrade Processing

A reboot of the client's service is required for finalizing the downgrade. Therefore, once a downgrade request is submitted the client will receive an email containing the next required steps to complete the downgrade process.

The downgrade to the client's service is not applied until they perform the required steps.

## Errors

All error responses have `success: false` and an `error` object.

| HTTP status | Code                           | Cause                                                                                                 |
| ----------- | ------------------------------ | ----------------------------------------------------------------------------------------------------- |
| `400`       | `invalid_parameter`            | The service number is not valid, or `new_plan` is not an accepted plan.                               |
| `400`       | `invalid_request`              | The request body is not valid JSON.                                                                   |
| `400`       | `missing_parameter`            | `new_plan` is missing, empty, or not a string.                                                        |
| `400`       | `invalid_state`                | The target is the current plan, the target is not a downgrade, or the current plan is not recognized. |
| `400`       | `invalid_state`                | The service is cancelled or terminated. The response includes `details.current_status`.               |
| `400`       | `service_pending_provisioning` | The service status is `pending`.                                                                      |
| `401`       | `authentication_failed`        | The API key is missing, invalid, or expired.                                                          |
| `403`       | `insufficient_permissions`     | The key lacks `admin:full`, or the request IP is not allowed.                                         |
| `404`       | `not_found`                    | The service does not exist in the broker account or access is denied.                                 |
| `429`       | `rate_limit_exceeded`          | The API key reached its rate limit. Use the `Retry-After` response header.                            |
| `500`       | `server_error`                 | Broker Panel could not create or queue the downgrade request, or an unexpected error occurred.        |


## OpenAPI

````yaml api/openapi.yaml POST /v1/services/{service_number}/downgrade
openapi: 3.1.0
info:
  title: Broker API
  version: 1.0.0
  description: API for broker-scoped service, request, and report operations.
servers:
  - url: https://brokers.newyorkcityservers.com/api
    description: Broker Panel API
security:
  - bearerAuth: []
tags:
  - name: Authentication
  - name: Services
  - name: Requests
  - name: Reports
paths:
  /v1/services/{service_number}/downgrade:
    post:
      tags:
        - Services
      summary: Downgrade Service
      description: >-
        Submits a service plan downgrade for background processing. Requires
        `admin:full`.
      operationId: downgradeService
      parameters:
        - $ref: '#/components/parameters/ServiceNumber'
      requestBody:
        $ref: '#/components/requestBodies/PlanChangeRequest'
      responses:
        '200':
          description: Downgrade accepted for processing.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessEnvelope'
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        $ref: '#/components/schemas/PlanChangeResult'
              example:
                success: true
                data:
                  request_id: REQ-002387
                  type: downgrade
                  request_status: accepted
                  service_number: 971100002
                  current_plan: Professional VPS
                  requested_plan: Standard VPS
                  submitted_date: '2026-06-21T15:10:00.000Z'
        '202':
          $ref: '#/components/responses/ReviewAccepted'
        '400':
          $ref: '#/components/responses/PlanChangeBadRequest'
        '401':
          $ref: '#/components/responses/AuthenticationError'
        '403':
          $ref: '#/components/responses/PermissionError'
        '404':
          $ref: '#/components/responses/ServiceNotFound'
        '429':
          $ref: '#/components/responses/RateLimitError'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  parameters:
    ServiceNumber:
      name: service_number
      in: path
      required: true
      description: Public service number parsed as a base-10 integer.
      schema:
        type: integer
        format: int64
  requestBodies:
    PlanChangeRequest:
      required: true
      content:
        application/json:
          schema:
            type: object
            required:
              - new_plan
            properties:
              new_plan:
                type: string
                description: >-
                  Target plan slug or label, accepted case-insensitively. Valid
                  slugs are basic-vps, standard-vps, professional-vps, and
                  dedicated-server.
          example:
            new_plan: standard-vps
  schemas:
    SuccessEnvelope:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
          const: true
        message:
          type: string
        pagination:
          $ref: '#/components/schemas/Pagination'
    PlanChangeResult:
      type: object
      required:
        - request_id
        - type
        - request_status
        - service_number
        - current_plan
        - requested_plan
        - submitted_date
      properties:
        request_id:
          type: string
        type:
          type: string
          enum:
            - upgrade
            - downgrade
        request_status:
          type: string
          const: accepted
        service_number:
          type: integer
        current_plan:
          type: string
        requested_plan:
          type: string
        submitted_date:
          type: string
          format: date-time
    Pagination:
      type: object
      required:
        - page
        - perPage
        - total
        - totalPages
      properties:
        page:
          type: integer
          minimum: 1
        perPage:
          type: integer
          minimum: 1
          maximum: 100
        total:
          type: integer
          minimum: 0
        totalPages:
          type: integer
          minimum: 0
    ReviewResult:
      type: object
      required:
        - request_id
        - request_status
        - message
      properties:
        request_id:
          type:
            - string
            - 'null'
        request_status:
          type: string
          enum:
            - pending
            - processing
            - nycservers_review
        message:
          type: string
        service_number:
          type:
            - integer
            - 'null'
        service_status:
          type: string
          const: pending
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          const: false
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: object
          additionalProperties: true
  responses:
    ReviewAccepted:
      description: Request accepted for NYCServers review.
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/SuccessEnvelope'
              - type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/ReviewResult'
          example:
            success: true
            data:
              request_id: REQ-002386
              request_status: nycservers_review
              message: >-
                There was a setup issue. Your request has been escalated for
                NYCS review. No need to resubmit.
    PlanChangeBadRequest:
      description: >-
        Codes `invalid_parameter`, `invalid_request`, `missing_parameter`,
        `invalid_state`, or `service_pending_provisioning`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidPlan:
              value:
                success: false
                error:
                  code: invalid_parameter
                  message: Invalid plan
                  details:
                    valid_values:
                      - basic-vps
                      - standard-vps
                      - professional-vps
                      - dedicated-server
            pendingService:
              value:
                success: false
                error:
                  code: service_pending_provisioning
                  message: >-
                    Service is still pending provisioning and this action is not
                    available yet.
    AuthenticationError:
      description: >-
        Code `authentication_failed` for a missing, malformed, invalid,
        inactive, or expired API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: authentication_failed
              message: Invalid API key
    PermissionError:
      description: >-
        Code `insufficient_permissions` when the request IP is not whitelisted
        or a required scope is missing.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: insufficient_permissions
              message: IP address not whitelisted
    ServiceNotFound:
      description: Code `not_found` when no broker-owned service matches.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: not_found
              message: Service not found or access denied
    RateLimitError:
      description: Code `rate_limit_exceeded` when the API key exceeds its rate limit.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: rate_limit_exceeded
              message: Rate limit exceeded
    ServerError:
      description: >-
        Code `server_error` when authentication or internal processing cannot
        complete.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: server_error
              message: Internal server error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: >-
        Send the API key in the Authorization bearer header. Production keys
        begin with `sk_live_`.

````