Proxy Discovery
Section titled “Proxy Discovery”The Proxy Discovery endpoints enumerate the proxy groups, services, and merged access rules attached to a container. Use these endpoints for inspection and debugging. The merged service view (permissions_raw and hooks) is non-authoritative and is intended for diagnostics only. For authoritative writes, use the dedicated permissions and hooks endpoints.
Container ID format
Section titled “Container ID format”Container IDs are 24-character lowercase hexadecimal ObjectIds. Requests with IDs in any other format are rejected with a 400 Bad Request. The examples below use 507f1f77bcf86cd799439012.
GET /api/v1/containers/{id}/proxy/groups
Section titled “GET /api/v1/containers/{id}/proxy/groups”Returns all defined group names for the container, along with the number of auth rules each group contains.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
Response
Section titled “Response”{ "statusCode": 200, "message": "Container proxy groups listed", "data": { "groups": [ { "name": "admins", "auth_rule_count": 3 }, { "name": "developers", "auth_rule_count": 5 }, { "name": "viewers", "auth_rule_count": 1 } ], "file_version": 12, "etag": "W/\"abc123def456\"" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 12, "action": "list_groups", "file_version": 12, "succeeded_count": 1, "failed_count": 0, "pending_count": 0, "target_count": 1, "retained_count": 1 }}| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP-style status code returned in the envelope |
message | string | Human-readable status message |
data.groups | array | Group names with auth-rule counts |
data.groups[].name | string | Group name as defined in the proxy config |
data.groups[].auth_rule_count | integer | Number of auth rules attached to the group |
data.file_version | integer | Monotonic version of the underlying proxy file |
data.etag | string | Weak ETag for the current file version |
propagation.committed | boolean | Whether the change has been committed to the file |
propagation.complete | boolean | Whether propagation has finished across all targets |
propagation.state | string | One of pending, applied, failed, unknown, superseded |
propagation.status_scope | string | One of current |
propagation.generation | integer | Monotonic generation number |
propagation.action | string | Action that produced this propagation record |
propagation.file_version | integer | File version associated with this propagation |
propagation.succeeded_count | integer | Targets that successfully applied the change |
propagation.failed_count | integer | Targets that failed to apply the change |
propagation.pending_count | integer | Targets still pending |
propagation.target_count | integer | Total targets targeted by the propagation |
propagation.retained_count | integer | Targets retaining the prior version |
Validation Error: the request does not match the operation schema, or its JSON body cannot be parsed. message names each failing check, and data, when present, lists them one entry per failing field.
{ "statusCode": 422, "error": "Validation Error", "message": "Validation failed: /name must NOT have fewer than 3 characters"}SDK and cURL
Section titled “SDK and cURL”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.proxy.groups.list('507f1f77bcf86cd799439012');curl -X GET https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439012/proxy/groups \ -H "Authorization: Bearer $HOODY_TOKEN"GET /api/v1/containers/{id}/proxy/services
Section titled “GET /api/v1/containers/{id}/proxy/services”Returns every service name referenced by any permission cell or hook rule in the container’s proxy config.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
Response
Section titled “Response”{ "statusCode": 200, "message": "Container proxy services listed", "data": { "services": ["api", "postgres", "redis", "storage"], "file_version": 12, "etag": "W/\"abc123def456\"" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 12, "action": "list_services", "file_version": 12, "succeeded_count": 1, "failed_count": 0, "pending_count": 0, "target_count": 1, "retained_count": 1 }}| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP-style status code returned in the envelope |
message | string | Human-readable status message |
data.services | array<string> | Service names referenced anywhere in the proxy config |
data.file_version | integer | Monotonic version of the underlying proxy file |
data.etag | string | Weak ETag for the current file version |
propagation.committed | boolean | Whether the change has been committed to the file |
propagation.complete | boolean | Whether propagation has finished across all targets |
propagation.state | string | One of pending, applied, failed, unknown, superseded |
propagation.status_scope | string | One of current |
propagation.generation | integer | Monotonic generation number |
propagation.action | string | Action that produced this propagation record |
propagation.file_version | integer | File version associated with this propagation |
propagation.succeeded_count | integer | Targets that successfully applied the change |
propagation.failed_count | integer | Targets that failed to apply the change |
propagation.pending_count | integer | Targets still pending |
propagation.target_count | integer | Total targets targeted by the propagation |
propagation.retained_count | integer | Targets retaining the prior version |
Validation Error: the request does not match the operation schema, or its JSON body cannot be parsed. message names each failing check, and data, when present, lists them one entry per failing field.
{ "statusCode": 422, "error": "Validation Error", "message": "Validation failed: /name must NOT have fewer than 3 characters"}SDK and cURL
Section titled “SDK and cURL”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.proxy.services.list('507f1f77bcf86cd799439012');curl -X GET https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439012/proxy/services \ -H "Authorization: Bearer $HOODY_TOKEN"GET /api/v1/containers/{id}/proxy/services/{service}
Section titled “GET /api/v1/containers/{id}/proxy/services/{service}”Returns a debug view of a single service: per-group access cells (permissions_raw), attached hooks, the effective default policy, and whether the service is reject-listed.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
Response
Section titled “Response”{ "statusCode": 200, "message": "Container proxy service details retrieved", "data": { "service": "postgres", "is_reject_listed": false, "permissions_raw": { "admins": { "access": "allow" }, "developers": { "access": "allow", "roles": ["read", "write"] }, "viewers": { "access": "deny" } }, "hooks": [ { "event": "connect", "action": "log" } ], "effective_default": "deny", "file_version": 12, "etag": "W/\"abc123def456\"" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 12, "action": "get_service", "file_version": 12, "succeeded_count": 1, "failed_count": 0, "pending_count": 0, "target_count": 1, "retained_count": 1 }}| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP-style status code returned in the envelope |
message | string | Human-readable status message |
data.service | string | Service name |
data.is_reject_listed | boolean | Whether the service is on the reject list |
data.permissions_raw | object | Per-group access cells for this service (debug shape) |
data.hooks | array | Hooks attached to this service (debug shape) |
data.effective_default | string | Effective default policy: allow or deny |
data.file_version | integer | Monotonic version of the underlying proxy file |
data.etag | string | Weak ETag for the current file version |
propagation.committed | boolean | Whether the change has been committed to the file |
propagation.complete | boolean | Whether propagation has finished across all targets |
propagation.state | string | One of pending, applied, failed, unknown, superseded |
propagation.status_scope | string | One of current |
propagation.generation | integer | Monotonic generation number |
propagation.action | string | Action that produced this propagation record |
propagation.file_version | integer | File version associated with this propagation |
propagation.succeeded_count | integer | Targets that successfully applied the change |
propagation.failed_count | integer | Targets that failed to apply the change |
propagation.pending_count | integer | Targets still pending |
propagation.target_count | integer | Total targets targeted by the propagation |
propagation.retained_count | integer | Targets retaining the prior version |
Validation Error: the request does not match the operation schema, or its JSON body cannot be parsed. message names each failing check, and data, when present, lists them one entry per failing field.
{ "statusCode": 422, "error": "Validation Error", "message": "Validation failed: /name must NOT have fewer than 3 characters"}SDK and cURL
Section titled “SDK and cURL”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.proxy.services.get('507f1f77bcf86cd799439012', 'postgres');curl -X GET https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439012/proxy/services/postgres \ -H "Authorization: Bearer $HOODY_TOKEN"