# Container Firewall

**Page:** api/container-firewall

[Download Raw Markdown](./api/container-firewall.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



## Container Firewall

The Container Firewall API controls ingress (inbound) and egress (outbound) network traffic for a container. Use these endpoints to list, add, toggle, remove, and reset firewall rules. Each container has independent rule sets for inbound and outbound traffic, and rules default to `state: "enabled"` when created.


Firewall rules are identified by their matching fields (protocol, ports, source/destination). To uniquely target a rule, provide enough filter fields in the request body to match a single rule.


### Firewall rule fields

Rules share a common shape across all endpoints:

| Field | Type | Description |
|-------|------|-------------|
| `action` | string | One of `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | One of `"tcp"`, `"udp"`, or `"icmp4"` |
| `description` | string | Human-readable rule description |
| `destination_port` | string | Port number, range (`80-90`), or comma-separated list (`80,443`). Required for TCP/UDP. |
| `source` | string | Source IPv4 address or CIDR range (ingress only) |
| `destination` | string | Destination IPv4 address or CIDR range (egress only) |
| `source_port` | string | Source port filter (rarely used) |
| `state` | string | `"enabled"` or `"disabled"`. Defaults to `"enabled"`. |
| `icmp_type` | string | ICMP type number (icmp4 protocol only) |
| `icmp_code` | string | ICMP code number (icmp4 protocol only) |

---

## List firewall rules

### `GET /api/v1/containers/{id}/firewall/rules`

Get all ingress and egress firewall rules for a container.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### SDK Usage

```typescript
const { data } = await client.api.firewall.listIterator({
  id: "c_abc123def456"
});
```

### cURL

```bash
curl -X GET "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/rules" \
  -H "Authorization: Bearer <token>"
```

### Response



```json
{
  "statusCode": 200,
  "message": "Firewall rules retrieved successfully",
  "data": {
    "ingress": [
      {
        "action": "allow",
        "protocol": "tcp",
        "description": "Allow HTTPS traffic",
        "destination_port": "443",
        "source": "0.0.0.0/0",
        "state": "enabled"
      },
      {
        "action": "allow",
        "protocol": "icmp4",
        "description": "Allow ping from any source",
        "source": "0.0.0.0/0",
        "state": "enabled",
        "icmp_type": "8",
        "icmp_code": "0"
      }
    ],
    "egress": [
      {
        "action": "allow",
        "protocol": "tcp",
        "description": "Allow outbound HTTPS",
        "destination_port": "443",
        "destination": "0.0.0.0/0",
        "state": "enabled"
      },
      {
        "action": "drop",
        "protocol": "tcp",
        "description": "Block outbound SMTP",
        "destination_port": "25",
        "destination": "0.0.0.0/0",
        "state": "enabled"
      }
    ]
  }
}
```


```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Authentication token required"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MISSING_TOKEN` | Authentication token missing | No authentication token was provided in the request | Include a valid JWT token in the Authorization header as `Bearer &lt;token&gt;` |
| `INVALID_TOKEN` | Invalid authentication token | The provided authentication token is malformed or invalid | Obtain a new token by logging in again or using a valid auth token |


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Insufficient permissions"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INSUFFICIENT_PERMISSIONS` | Insufficient permissions | You do not have the required permissions to perform this action | Contact the resource owner or administrator to request access |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Container not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `CONTAINER_NOT_FOUND` | Container not found | The requested container does not exist or you do not have permission to access it. | Verify the container ID is correct and that you have access to the project it belongs to. |



---

## Add firewall rules

The `addEgressRule` and `addIngressRule` endpoints append a single rule to the specified direction. If an equivalent rule already exists, the API returns `200` with a `duplicate` flag in the data; otherwise it returns `201`.

### `POST /api/v1/containers/{id}/firewall/ingress`

Add a new ingress (inbound) firewall rule to a container. Use this endpoint to control which traffic can reach your container. All rules default to `state: "enabled"` if not specified.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `action` | string | Yes | One of `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | Yes | One of `"tcp"`, `"udp"`, or `"icmp4"` |
| `description` | string | Yes | Human-readable rule description |
| `destination_port` | string | No | Port number, range (`80-90`), or comma-separated list (`80,443`). Required for TCP/UDP. |
| `source` | string | No | Source IPv4 address or CIDR range. Use `0.0.0.0/0` for any source. |
| `source_port` | string | No | Source port filter (rarely used) |
| `state` | string | No | `"enabled"` or `"disabled"`. Defaults to `"enabled"`. |
| `icmp_type` | string | No | ICMP type number (e.g., `8` for echo request/ping) |
| `icmp_code` | string | No | ICMP code number |

### SDK Usage

```typescript
await client.api.firewall.addIngressRule({
  id: "c_abc123def456",
  data: {
    action: "allow",
    protocol: "tcp",
    description: "Allow HTTPS",
    destination_port: "443",
    source: "0.0.0.0/0"
  }
});
```

### cURL

```bash
curl -X POST "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/ingress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "allow",
    "protocol": "tcp",
    "description": "Allow HTTPS",
    "destination_port": "443",
    "source": "0.0.0.0/0"
  }'
```

### Response



```json
{
  "statusCode": 201,
  "message": "Ingress rule added successfully",
  "data": {}
}
```


Returned when an equivalent rule already exists.

```json
{
  "statusCode": 200,
  "message": "Rule already exists",
  "data": {}
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid request body"
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Container not found"
}
```



---

### `POST /api/v1/containers/{id}/firewall/egress`

Add a new egress (outbound) firewall rule to a container. Use this endpoint to control which traffic your container can send. All rules default to `state: "enabled"` if not specified.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `action` | string | Yes | One of `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | Yes | One of `"tcp"`, `"udp"`, or `"icmp4"` |
| `description` | string | Yes | Human-readable rule description |
| `destination_port` | string | No | Port number, range (`80-90`), or comma-separated list (`80,443`). Required for TCP/UDP. |
| `destination` | string | No | Destination IPv4 address or CIDR range. Use `0.0.0.0/0` for any destination. |
| `source_port` | string | No | Source port filter (rarely used) |
| `state` | string | No | `"enabled"` or `"disabled"`. Defaults to `"enabled"`. |
| `icmp_type` | string | No | ICMP type number |
| `icmp_code` | string | No | ICMP code number |

### SDK Usage

```typescript
await client.api.firewall.addEgressRule({
  id: "c_abc123def456",
  data: {
    action: "allow",
    protocol: "tcp",
    description: "Allow outbound HTTPS",
    destination_port: "443",
    destination: "0.0.0.0/0"
  }
});
```

### cURL

```bash
curl -X POST "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/egress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "allow",
    "protocol": "tcp",
    "description": "Allow outbound HTTPS",
    "destination_port": "443",
    "destination": "0.0.0.0/0"
  }'
```

### Response



```json
{
  "statusCode": 201,
  "message": "Egress rule added successfully",
  "data": {}
}
```


Returned when an equivalent rule already exists.

```json
{
  "statusCode": 200,
  "message": "Rule already exists",
  "data": {}
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid request body"
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Container not found"
}
```



---

## Toggle firewall rules

The `toggleIngressRule` and `toggleEgressRule` endpoints change the `state` of an existing rule without deleting it. The body identifies the rule by matching fields and supplies the new `state`.

### `PATCH /api/v1/containers/{id}/firewall/ingress`

Enable or disable an ingress (inbound) firewall rule without deleting it. Provide filters to identify which rule to toggle. Useful for temporarily disabling rules.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `state` | string | Yes | New state: `"enabled"` or `"disabled"` |
| `action` | string | No | Filter by action: `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | No | Filter by protocol: `"tcp"`, `"udp"`, or `"icmp4"` |
| `destination_port` | string | No | Filter by destination port, range, or list |
| `source_port` | string | No | Filter by source port |
| `source` | string | No | Filter by source IPv4/CIDR |
| `description` | string | No | Filter by rule description |
| `icmp_type` | string | No | Filter by ICMP type number |
| `icmp_code` | string | No | Filter by ICMP code number |

### SDK Usage

```typescript
await client.api.firewall.toggleIngressRule({
  id: "c_abc123def456",
  data: {
    state: "disabled",
    protocol: "tcp",
    destination_port: "443"
  }
});
```

### cURL

```bash
curl -X PATCH "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/ingress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "disabled",
    "protocol": "tcp",
    "destination_port": "443"
  }'
```

### Response



```json
{
  "statusCode": 200,
  "message": "Ingress rule state toggled successfully",
  "data": {
    "direction": "ingress",
    "new_state": "disabled",
    "updated": {
      "action": "allow",
      "protocol": "tcp",
      "description": "Allow HTTPS traffic",
      "destination_port": "443",
      "source": "0.0.0.0/0",
      "state": "disabled"
    }
  }
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Matching ingress rule not found"
}
```



---

### `PATCH /api/v1/containers/{id}/firewall/egress`

Enable or disable an egress (outbound) firewall rule without deleting it. Provide filters to identify which rule to toggle. Useful for temporarily disabling rules.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `state` | string | Yes | New state: `"enabled"` or `"disabled"` |
| `action` | string | No | Filter by action: `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | No | Filter by protocol: `"tcp"`, `"udp"`, or `"icmp4"` |
| `destination_port` | string | No | Filter by destination port, range, or list |
| `source_port` | string | No | Filter by source port |
| `destination` | string | No | Filter by destination IPv4/CIDR |
| `description` | string | No | Filter by rule description |
| `icmp_type` | string | No | Filter by ICMP type number |
| `icmp_code` | string | No | Filter by ICMP code number |

### SDK Usage

```typescript
await client.api.firewall.toggleEgressRule({
  id: "c_abc123def456",
  data: {
    state: "disabled",
    protocol: "tcp",
    destination_port: "25"
  }
});
```

### cURL

```bash
curl -X PATCH "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/egress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "disabled",
    "protocol": "tcp",
    "destination_port": "25"
  }'
```

### Response



```json
{
  "statusCode": 200,
  "message": "Egress rule state toggled successfully",
  "data": {
    "direction": "egress",
    "new_state": "enabled",
    "updated": {
      "action": "allow",
      "protocol": "tcp",
      "description": "Allow outbound HTTPS",
      "destination_port": "443",
      "destination": "0.0.0.0/0",
      "state": "enabled"
    }
  }
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Matching egress rule not found"
}
```



---

## Remove firewall rules

The `removeIngressRule` and `removeEgressRule` endpoints delete one or more rules. By default, only the first matching rule is removed; pass `all: true` to remove every rule that matches the supplied filters, or pass `all: true` alone to remove all rules in that direction.


Removing rules is not equivalent to resetting the firewall. `remove*` deletes rules but leaves the firewall/ACL attached to the container. Use the `reset` endpoint to detach the firewall entirely.


### `DELETE /api/v1/containers/{id}/firewall/ingress`

Remove one or more ingress (inbound) firewall rules. Provide filters to match specific rules, or use `all: true` to remove all ingress rules. Not equivalent to reset - this only deletes rules and leaves the firewall/ACL attached.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `all` | boolean | No | Remove all matching rules (default: first match only). Set to `true` with no other filters to remove all ingress rules. |
| `action` | string | No | Filter by action: `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | No | Filter by protocol: `"tcp"`, `"udp"`, or `"icmp4"` |
| `destination_port` | string | No | Filter by destination port, range, or list |
| `source` | string | No | Filter by source IPv4/CIDR |
| `source_port` | string | No | Filter by source port |
| `description` | string | No | Filter by rule description |
| `state` | string | No | Filter by state. Defaults to `"enabled"`. |
| `icmp_type` | string | No | Filter by ICMP type number |
| `icmp_code` | string | No | Filter by ICMP code number |

### SDK Usage

```typescript
// Remove a specific rule
await client.api.firewall.removeIngressRule({
  id: "c_abc123def456",
  data: {
    protocol: "tcp",
    destination_port: "22",
    source: "192.168.1.0/24"
  }
});

// Remove all ingress rules
await client.api.firewall.removeIngressRule({
  id: "c_abc123def456",
  data: { all: true }
});
```

### cURL

```bash
curl -X DELETE "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/ingress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "tcp",
    "destination_port": "22",
    "source": "192.168.1.0/24"
  }'
```

### Response



```json
{
  "statusCode": 200,
  "message": "Ingress rule removed successfully",
  "data": {
    "direction": "ingress",
    "removed_count": 1,
    "removed": [
      {
        "action": "allow",
        "protocol": "tcp",
        "description": "Allow SSH from office",
        "destination_port": "22",
        "source": "192.168.1.0/24",
        "state": "enabled"
      }
    ]
  }
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Matching ingress rule not found"
}
```



---

### `DELETE /api/v1/containers/{id}/firewall/egress`

Remove one or more egress (outbound) firewall rules. Provide filters to match specific rules, or use `all: true` to remove all egress rules. Not equivalent to reset - this only deletes rules and leaves the firewall/ACL attached.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `all` | boolean | No | Remove all matching rules (default: first match only). Set to `true` with no other filters to remove all egress rules. |
| `action` | string | No | Filter by action: `"allow"`, `"reject"`, or `"drop"` |
| `protocol` | string | No | Filter by protocol: `"tcp"`, `"udp"`, or `"icmp4"` |
| `destination_port` | string | No | Filter by destination port, range, or list |
| `destination` | string | No | Filter by destination IPv4/CIDR |
| `source_port` | string | No | Filter by source port |
| `description` | string | No | Filter by rule description |
| `state` | string | No | Filter by state. Defaults to `"enabled"`. |
| `icmp_type` | string | No | Filter by ICMP type number |
| `icmp_code` | string | No | Filter by ICMP code number |

### SDK Usage

```typescript
// Remove a specific rule
await client.api.firewall.removeEgressRule({
  id: "c_abc123def456",
  data: {
    protocol: "tcp",
    destination_port: "25"
  }
});

// Remove all egress rules
await client.api.firewall.removeEgressRule({
  id: "c_abc123def456",
  data: { all: true }
});
```

### cURL

```bash
curl -X DELETE "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/egress" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "tcp",
    "destination_port": "25"
  }'
```

### Response



```json
{
  "statusCode": 200,
  "message": "Egress rules removed successfully",
  "data": {
    "direction": "egress",
    "removed_count": 2,
    "removed": [
      {
        "action": "allow",
        "protocol": "tcp",
        "description": "Allow outbound HTTPS",
        "destination_port": "443",
        "destination": "0.0.0.0/0",
        "state": "enabled"
      },
      {
        "action": "allow",
        "protocol": "tcp",
        "description": "Allow outbound DNS",
        "destination_port": "53",
        "destination": "8.8.8.8",
        "state": "enabled"
      }
    ]
  }
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Matching egress rule not found"
}
```



---

## Reset firewall

### `POST /api/v1/containers/{id}/firewall/reset`

Delete the ACL and detach the container from the firewall bridge, returning the container to an open network state. Use this when you want to fully disable the firewall rather than remove individual rules.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Container ID |

### SDK Usage

```typescript
await client.api.firewall.reset({
  id: "c_abc123def456"
});
```

### cURL

```bash
curl -X POST "https://api.hoody.com/api/v1/containers/c_abc123def456/firewall/reset" \
  -H "Authorization: Bearer <token>"
```

### Response



```json
{
  "statusCode": 200,
  "message": "Firewall reset successfully",
  "data": {
    "rules": {
      "ingress": [],
      "egress": []
    }
  }
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Container not found"
}
```