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

# Delete Expense Category

> Delete a custom expense category from your firm

## Overview

The Delete Expense Category endpoint allows you to permanently remove custom expense categories that are no longer needed. This operation has strict safety checks to prevent data loss.

**Important Restrictions**:

* You can only delete **custom categories** that you created
* **System default categories** cannot be deleted
* Categories must have **no expenses** assigned to them
* Categories must have **no subcategories** under them
* Categories must belong to your firm

## Path Parameters

<ParamField path="id" type="integer" required>
  The unique identifier of the expense category to delete
</ParamField>

## Safety Checks

Before deleting a category, the system performs several validation checks:

1. **System Protection**: Cannot delete system/default categories
2. **Usage Check**: Cannot delete categories that have expenses assigned
3. **Hierarchy Check**: Cannot delete categories that have subcategories
4. **Ownership**: Can only delete categories belonging to your firm

## Response

<ResponseField name="message" type="string">
  Success message confirming the category deletion
</ResponseField>

<ResponseField name="id" type="integer">
  The ID of the deleted category
</ResponseField>

## Pre-Deletion Checklist

Before attempting to delete a category:

1. **Move or delete all expenses** using this category
2. **Delete or reassign all subcategories** under this category
3. **Confirm it's a custom category** (not a system default)

<RequestExample>
  ```bash Delete Category theme={null}
  curl -X DELETE "https://api.contazen.ro/v1/expense-categories/25" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript Delete Category theme={null}
  const categoryId = 25;

  const response = await fetch(`https://api.contazen.ro/v1/expense-categories/${categoryId}`, {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    }
  });

  const data = await response.json();
  if (data.success) {
    console.log('Category deleted:', data.message);
  } else {
    console.error('Delete failed:', data.error.message);
  }
  ```

  ```javascript Safe Delete with Checks theme={null}
  const categoryId = 25;

  // First, check if category can be deleted
  const checkResponse = await fetch(`https://api.contazen.ro/v1/expense-categories/${categoryId}`, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    }
  });

  const categoryData = await checkResponse.json();
  if (categoryData.category.type === 'system') {
    console.error('Cannot delete system category');
    return;
  }

  // Proceed with deletion
  const deleteResponse = await fetch(`https://api.contazen.ro/v1/expense-categories/${categoryId}`, {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    }
  });

  const result = await deleteResponse.json();
  console.log('Delete result:', result);
  ```

  ```php Delete Category theme={null}
  $categoryId = 25;

  $curl = curl_init();

  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.contazen.ro/v1/expense-categories/{$categoryId}",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_CUSTOMREQUEST => 'DELETE',
      CURLOPT_HTTPHEADER => [
          'Authorization: Bearer YOUR_API_KEY',
          'Content-Type: application/json'
      ]
  ]);

  $response = curl_exec($curl);
  $data = json_decode($response, true);
  curl_close($curl);

  if ($data['success']) {
      echo 'Category deleted: ' . $data['message'];
  } else {
      echo 'Delete failed: ' . $data['error']['message'];
  }
  ```

  ```php Safe Delete with Validation theme={null}
  $categoryId = 25;

  // First check the category type
  $curl = curl_init();
  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.contazen.ro/v1/expense-categories/{$categoryId}",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          'Authorization: Bearer YOUR_API_KEY',
          'Content-Type: application/json'
      ]
  ]);

  $response = curl_exec($curl);
  $categoryData = json_decode($response, true);

  if ($categoryData['category']['type'] === 'system') {
      echo 'Error: Cannot delete system category';
      exit;
  }

  // Proceed with deletion
  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.contazen.ro/v1/expense-categories/{$categoryId}",
      CURLOPT_CUSTOMREQUEST => 'DELETE'
  ]);

  $deleteResponse = curl_exec($curl);
  $deleteData = json_decode($deleteResponse, true);
  curl_close($curl);

  if ($deleteData['success']) {
      echo 'Successfully deleted category ID: ' . $deleteData['id'];
  } else {
      echo 'Delete failed: ' . $deleteData['error']['message'];
      if (isset($deleteData['error']['expense_count'])) {
          echo ' (Has ' . $deleteData['error']['expense_count'] . ' expenses)';
      }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "success": true,
    "message": "Category deleted successfully",
    "id": 25
  }
  ```

  ```json 400 - Missing ID theme={null}
  {
    "success": false,
    "error": {
      "message": "Category ID is required",
      "type": "invalid_request_error",
      "code": "parameter_missing",
      "param": "id"
    }
  }
  ```

  ```json 404 - Not Found theme={null}
  {
    "success": false,
    "error": {
      "message": "Category not found",
      "type": "invalid_request_error",
      "code": "resource_missing",
      "param": "id"
    }
  }
  ```

  ```json 403 - System Category theme={null}
  {
    "success": false,
    "error": {
      "message": "Cannot delete system category",
      "type": "invalid_request_error",
      "code": "system_category"
    }
  }
  ```

  ```json 400 - Has Expenses theme={null}
  {
    "success": false,
    "error": {
      "message": "Category has expenses assigned and cannot be deleted",
      "type": "invalid_request_error",
      "code": "category_in_use",
      "expense_count": 15
    }
  }
  ```

  ```json 400 - Has Subcategories theme={null}
  {
    "success": false,
    "error": {
      "message": "Category has subcategories and cannot be deleted",
      "type": "invalid_request_error",
      "code": "category_has_children",
      "subcategory_count": 3
    }
  }
  ```

  ```json 403 - Permission Denied theme={null}
  {
    "success": false,
    "error": {
      "message": "You don't have permission to delete categories",
      "type": "invalid_request_error",
      "code": "permission_denied"
    }
  }
  ```

  ```json 500 - Delete Failed theme={null}
  {
    "success": false,
    "error": {
      "message": "Failed to delete category",
      "type": "api_error",
      "code": "delete_failed"
    }
  }
  ```
</ResponseExample>

## Best Practices

### Before Deleting Categories

1. **Check Dependencies**: Use the List Expenses API to find expenses using this category
2. **Reassign Expenses**: Move expenses to different categories before deletion
3. **Handle Subcategories**: Delete or reassign all subcategories first
4. **Backup Important Data**: Export expense data if the category contains historical records

### Alternative to Deletion

Instead of deleting categories, consider:

* **Hide Categories**: Set `is_visible: false` to hide unused categories
* **Rename Categories**: Update the name for repurposing
* **Archive Approach**: Keep historical categories for reporting consistency


## OpenAPI

````yaml DELETE /expense-categories/{id}
openapi: 3.1.0
info:
  title: Contazen API
  version: 1.2.0
  description: >
    Build powerful integrations with the Contazen invoicing platform. The
    Contazen API is organized around REST, 

    has predictable resource-oriented URLs, accepts JSON request bodies, returns
    JSON-encoded responses, 

    and uses standard HTTP response codes, authentication, and verbs.


    ## Authentication

    The API uses Bearer token authentication. Include your API key in the
    Authorization header.


    ### Getting your API Key

    1. Log in to your Contazen account

    2. Navigate to Settings > API

    3. Generate or copy your API key (starts with `sk_live_` for production or
    `sk_test_` for testing)


    ### Using the API Key

    Include your API key in the Authorization header:

    ```

    Authorization: Bearer sk_live_YOUR_API_KEY

    ```


    ### Example Request with cURL

    ```bash

    curl --request GET \
      --url https://api.contazen.ro/v1/clients \
      --header 'Authorization: Bearer sk_live_YOUR_API_KEY' \
      --header 'Accept: application/json'
    ```


    ## Rate Limiting

    - 1000 requests per hour per API key

    - 100 create operations per minute per API key


    Rate limit information is included in response headers:

    - `X-RateLimit-Limit`: Maximum requests allowed

    - `X-RateLimit-Remaining`: Requests remaining

    - `X-RateLimit-Reset`: Reset time (Unix timestamp)


    ## Pagination

    All list endpoints return paginated results with the following format:

    ```json

    {
      "success": true,
      "data": {
        "object": "list",
        "data": [...],
        "has_more": true,
        "total": 245,
        "page": 1,
        "per_page": 50,
        "total_pages": 5
      },
      "meta": {
        "version": "v1",
        "request_id": "req_1a2b3c4d",
        "response_time": "23.45ms"
      }
    }

    ```


    ## Multi-Work-Point Access

    API keys belong to a specific work point but can access data from all work
    points

    within the same parent company.


    ## Error Handling

    The API uses conventional HTTP response codes to indicate success or
    failure. 

    In general: 2xx codes indicate success, 4xx codes indicate an error due to
    the 

    information provided, and 5xx codes indicate an error with Contazen's
    servers.


    ## Expanding Nested Objects

    Many endpoints support the `expand` parameter to include related objects in
    the response.

    This follows the Stripe API pattern. For example:

    - `expand[]=lines` - Include invoice line items

    - `expand[]=payments` - Include payment records

    - `expand[]=client` - Include full client object


    ## Localization

    The API supports multiple languages through:

    - `locale` query parameter (en, ro)

    - `Accept-Language` header

    - Default: English
  contact:
    name: Contazen Support
    email: support@contazen.ro
    url: https://contazen.ro
  license:
    name: Proprietary
    url: https://www.contazen.ro/termeni-si-conditii-de-utilizare/
servers:
  - url: https://api.contazen.ro/v1
    description: Production API server
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: API authentication and test endpoints
  - name: Clients
    description: Manage your customers (B2B and B2C)
  - name: Invoices
    description: Create and manage invoices, proformas, and receipts
  - name: Products
    description: Manage your product and service catalog
  - name: Expenses
    description: Track and manage business expenses
  - name: Expense Categories
    description: Organize expenses with categories
  - name: Suppliers
    description: Manage expense suppliers and vendors
  - name: Settings
    description: API settings and configuration
  - name: Payments
    description: Payments received against invoices
  - name: Receipts
    description: Cash receipts (chitanțe) — standalone or paired with an invoice
  - name: Company Lookup
    description: Romanian company lookup (ANAF / VIES)
  - name: Invoice Series
    description: Manage invoice numbering series
  - name: Bank Accounts
    description: Manage IBAN bank accounts
  - name: E-Factura
    description: Romanian e-invoicing status and configuration
  - name: Supplier Bills
    description: Supplier invoices imported from the ANAF SPV inbox
  - name: VAT Rates
    description: Firm-scoped custom VAT rates on top of the Romanian catalog
  - name: Currencies
    description: Currencies enabled for the firm's bill templates
  - name: Languages
    description: Languages enabled for the firm's bill templates
  - name: Conta
    description: |
      Public ANAF data for the firm's CUI: fiscal profile (TVA scope, RTVAI,
      split TVA, status, e-Factura registration, CAEN) and annual balance
      sheets (cifra de afaceri, profit, capitaluri, datorii, salariați).

      Powered by the public ANAF webservices (no OAuth required for these
      endpoints). The data is cached locally and refreshed on demand via
      the `/sync` actions.
paths:
  /expense-categories/{id}:
    delete:
      tags:
        - Expense Categories
      summary: Delete expense category
      description: >-
        Delete a custom expense category (cannot delete system categories or
        categories with expenses)
      operationId: deleteExpenseCategory
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Category ID
      responses:
        '200':
          description: Category deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  meta:
                    $ref: '#/components/schemas/ResponseMeta'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          description: Cannot delete system categories or categories with expenses
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          $ref: '#/components/responses/NotFoundError'
components:
  schemas:
    ResponseMeta:
      type: object
      properties:
        version:
          type: string
          default: v1
        request_id:
          type: string
          format: uuid
          description: Unique request identifier for debugging
        response_time:
          type: string
          example: 23.45ms
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          default: false
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
              description: Human-readable error message
            type:
              type: string
              enum:
                - api_error
                - authentication_error
                - invalid_request_error
                - rate_limit_error
                - permission_error
                - validation_error
            code:
              type: string
              description: Machine-readable error code
            param:
              type: string
              description: The parameter that caused the error
            doc_url:
              type: string
              format: uri
              description: URL to relevant documentation
        meta:
          $ref: '#/components/schemas/ResponseMeta'
  responses:
    UnauthorizedError:
      description: API key is missing or invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFoundError:
      description: The specified resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Use your API key (sk_live_xxx or sk_test_xxx)

````