Proxy Hooks
Section titled “Proxy Hooks”Register MITM hook scripts that intercept container traffic before it reaches the real service. Hooks are organized per-service with first-match-wins semantics, and all mutating operations are ETag-gated via the If-Match header. Use these endpoints to list, create, replace, reorder, and delete proxy hooks for a container.
List all proxy hooks for a container
Section titled “List all proxy hooks for a container”GET /api/v1/containers/{id}/proxy/hooks
Returns all hooks grouped by service for the given container, with the current ETag.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
curl -X GET \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.list('890abcdef12345678901cdef');console.log(res.data);{ "statusCode": 200, "message": "Proxy hooks listed successfully", "data": { "hooks": { "api": [ { "id": "01h8x3kq7v4mz0qy6f3t8n2rxd", "position": 0, "match": { "method": "GET", "path": "/v1/users/*" }, "script": { "path": "/hooks/auth-check.js" }, "timeout": 5000 }, { "id": "01h8x3kq8w5n1rz7g4v9p3syfa", "position": 1, "match": { "method": ["POST", "PUT"], "path": "/v1/projects/*" }, "script": { "subdomain": "api", "execId": "exec_abc123", "path": "/hooks/validate-payload.js" }, "timeout": 10000, "applies_to": { "groups": ["admins"] } } ], "logs": [ { "id": "01h8x3kq9x6p2sa8h5vp4tzgk7", "position": 0, "match": { "method": "*" }, "script": { "path": "/hooks/log-all.js" }, "timeout": 3000 } ] }, "file_version": 42, "etag": "file:v42" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 7, "action": "list", "file_version": 42, "succeeded_count": 3, "failed_count": 0, "pending_count": 0, "target_count": 3, "retained_count": 3 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
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"}List hooks for a specific service
Section titled “List hooks for a specific service”GET /api/v1/containers/{id}/proxy/hooks/{service}
Returns the ordered hook array for a single service. First-match-wins within this list.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
curl -X GET \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.listByService( '890abcdef12345678901cdef', 'api');console.log(res.data);{ "statusCode": 200, "message": "Service hooks listed successfully", "data": { "service": "api", "hooks": [ { "id": "01h8x3kq7v4mz0qy6f3t8n2rxd", "position": 0, "match": { "method": "GET", "path": "/v1/users/*" }, "script": { "path": "/hooks/auth-check.js" }, "timeout": 5000 }, { "id": "01h8x3kq8w5n1rz7g4v9p3syfa", "position": 1, "match": { "method": ["POST", "PUT"], "path": "/v1/projects/*", "headers": { "X-Webhook-Source": "github" } }, "script": { "subdomain": "api", "execId": "exec_abc123", "path": "/hooks/validate-payload.js" }, "timeout": 10000, "applies_to": { "groups": ["admins"] } } ], "file_version": 42, "etag": "file:v42" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 7, "action": "list", "file_version": 42, "succeeded_count": 2, "failed_count": 0, "pending_count": 0, "target_count": 2, "retained_count": 2 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
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"}Get a single hook by id
Section titled “Get a single hook by id”GET /api/v1/containers/{id}/proxy/hooks/{service}/{hookId}
Retrieves a single hook by its ULID within a specific service.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
hookId | path | string | Yes | 26-char Crockford base32 ULID (lowercase) |
curl -X GET \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api/01h8x3kq7v4mz0qy6f3t8n2rxd \ -H "Authorization: Bearer $HOODY_TOKEN"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.get( '890abcdef12345678901cdef', 'api', '01h8x3kq7v4mz0qy6f3t8n2rxd');console.log(res.data);{ "statusCode": 200, "message": "Hook retrieved successfully", "data": { "hook": { "id": "01h8x3kq7v4mz0qy6f3t8n2rxd", "position": 0, "match": { "method": "GET", "path": "/v1/users/*" }, "script": { "path": "/hooks/auth-check.js" }, "timeout": 5000 }, "file_version": 42, "etag": "file:v42" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 7, "action": "get", "file_version": 42, "succeeded_count": 1, "failed_count": 0, "pending_count": 0, "target_count": 1, "retained_count": 1 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
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"}Append or insert a new hook
Section titled “Append or insert a new hook”POST /api/v1/containers/{id}/proxy/hooks/{service}
Create a new hook under a service. Requires the If-Match: file:v<N> header. Omit position to append to the end of the service’s hook array.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
if-match | header | string | Yes | file:v<N> ETag precondition |
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
match | object | Yes | Match criteria for intercepting requests |
match.method | string or array | No | HTTP method or array of methods (*, GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) |
match.path | string | No | URL path pattern (max 257 chars) |
match.headers | object | No | Header key-value pairs to match |
script | object | Yes | Script to execute when the hook matches |
script.path | string | Yes | Path to the hook script |
script.subdomain | string | No | Subdomain for the script execution target |
script.execId | string | No | Execution ID for the script |
timeout | integer | No | Timeout in milliseconds (1-30000) |
applies_to | object | No | Group-based targeting |
applies_to.groups | array | No | Array of group names (min 1 item) |
position | integer | No | 0-indexed insertion position (omit to append) |
curl -X POST \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "If-Match: file:v42" \ -H "Content-Type: application/json" \ -d '{ "match": { "method": "DELETE", "path": "/v1/projects/*" }, "script": { "path": "/hooks/audit-delete.js" }, "timeout": 8000, "applies_to": { "groups": ["auditors"] } }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.create( '890abcdef12345678901cdef', 'api', { match: { method: 'DELETE', path: '/v1/projects/*' }, script: { path: '/hooks/audit-delete.js' }, timeout: 8000, applies_to: { groups: ['auditors'] } }, { ifMatch: 'file:v42' });console.log(res.data);{ "statusCode": 201, "message": "Hook created successfully", "data": { "hook": { "id": "01h8x3kr0y7p3tb9j6wq5v0hmn", "position": 2, "match": { "method": "DELETE", "path": "/v1/projects/*" }, "script": { "path": "/hooks/audit-delete.js" }, "timeout": 8000, "applies_to": { "groups": ["auditors"] } }, "file_version": 43, "etag": "file:v43" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 8, "action": "add", "file_version": 43, "succeeded_count": 3, "failed_count": 0, "pending_count": 0, "target_count": 3, "retained_count": 3 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
{ "statusCode": 412, "error": "Precondition Failed", "message": "etag_mismatch"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 412 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 412 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 412 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 412 | The If-Match header does not match the current file_version |
{ "statusCode": 422, "error": "Validation Error", "message": "Invalid hook"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 422 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 422 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 422 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 422 | The If-Match header does not match the current file_version |
{ "statusCode": 428, "error": "Precondition Required", "message": "If-Match header required for this operation"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 428 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 428 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 428 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 428 | The If-Match header does not match the current file_version |
Replace a hook in place
Section titled “Replace a hook in place”PUT /api/v1/containers/{id}/proxy/hooks/{service}/{hookId}
Full-replace a hook preserving its id and position. Requires the If-Match header. The same path also accepts PATCH as a live alias for this operation.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
hookId | path | string | Yes | 26-char Crockford base32 ULID (lowercase) |
if-match | header | string | Yes | file:v<N> ETag precondition |
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
match | object | Yes | Match criteria for intercepting requests |
match.method | string or array | No | HTTP method or array of methods (*, GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) |
match.path | string | No | URL path pattern (max 257 chars) |
match.headers | object | No | Header key-value pairs to match |
script | object | Yes | Script to execute when the hook matches |
script.path | string | Yes | Path to the hook script |
script.subdomain | string | No | Subdomain for the script execution target |
script.execId | string | No | Execution ID for the script |
timeout | integer | No | Timeout in milliseconds (1-30000) |
applies_to | object | No | Group-based targeting |
applies_to.groups | array | No | Array of group names (min 1 item) |
position | integer | No | 0-indexed insertion position (POST only) |
curl -X PUT \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api/01h8x3kq7v4mz0qy6f3t8n2rxd \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "If-Match: file:v42" \ -H "Content-Type: application/json" \ -d '{ "match": { "method": "GET", "path": "/v1/users/*", "headers": { "X-Internal": "true" } }, "script": { "path": "/hooks/auth-check-v2.js", "execId": "exec_def456" }, "timeout": 7000 }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.set( '890abcdef12345678901cdef', 'api', '01h8x3kq7v4mz0qy6f3t8n2rxd', { match: { method: 'GET', path: '/v1/users/*', headers: { 'X-Internal': 'true' } }, script: { path: '/hooks/auth-check-v2.js', execId: 'exec_def456' }, timeout: 7000 }, { ifMatch: 'file:v42' });console.log(res.data);{ "statusCode": 200, "message": "Hook updated successfully", "data": { "hook": { "id": "01h8x3kq7v4mz0qy6f3t8n2rxd", "position": 0, "match": { "method": "GET", "path": "/v1/users/*", "headers": { "X-Internal": "true" } }, "script": { "path": "/hooks/auth-check-v2.js", "execId": "exec_def456" }, "timeout": 7000 }, "file_version": 43, "etag": "file:v43" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 8, "action": "update", "file_version": 43, "succeeded_count": 3, "failed_count": 0, "pending_count": 0, "target_count": 3, "retained_count": 3 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
{ "statusCode": 412, "error": "Precondition Failed", "message": "etag_mismatch"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 412 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 412 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 412 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 412 | The If-Match header does not match the current file_version |
{ "statusCode": 422, "error": "Validation Error", "message": "Invalid hook"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 422 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 422 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 422 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 422 | The If-Match header does not match the current file_version |
{ "statusCode": 428, "error": "Precondition Required", "message": "If-Match header required for this operation"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 428 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 428 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 428 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 428 | The If-Match header does not match the current file_version |
Move a hook to a new position
Section titled “Move a hook to a new position”PATCH /api/v1/containers/{id}/proxy/hooks/{service}/{hookId}/position
Atomically move a hook to a new 0-indexed position within its service array. Requires the If-Match header.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
hookId | path | string | Yes | 26-char Crockford base32 ULID (lowercase) |
if-match | header | string | Yes | file:v<N> ETag precondition |
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
position | integer | Yes | New 0-indexed position (minimum 0) |
curl -X PATCH \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api/01h8x3kq8w5n1rz7g4v9p3syfa/position \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "If-Match: file:v42" \ -H "Content-Type: application/json" \ -d '{ "position": 0 }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.move( '890abcdef12345678901cdef', 'api', '01h8x3kq8w5n1rz7g4v9p3syfa', { position: 0 }, { ifMatch: 'file:v42' });console.log(res.data);{ "statusCode": 200, "message": "Hook moved successfully", "data": { "hook": { "id": "01h8x3kq8w5n1rz7g4v9p3syfa", "position": 0, "match": { "method": ["POST", "PUT"], "path": "/v1/projects/*" }, "script": { "subdomain": "api", "execId": "exec_abc123", "path": "/hooks/validate-payload.js" }, "timeout": 10000, "applies_to": { "groups": ["admins"] } }, "file_version": 43, "etag": "file:v43" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 8, "action": "move", "file_version": 43, "succeeded_count": 3, "failed_count": 0, "pending_count": 0, "target_count": 3, "retained_count": 3 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
{ "statusCode": 412, "error": "Precondition Failed", "message": "etag_mismatch"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 412 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 412 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 412 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 412 | The If-Match header does not match the current file_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"}{ "statusCode": 428, "error": "Precondition Required", "message": "If-Match header required for this operation"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 428 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 428 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 428 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 428 | The If-Match header does not match the current file_version |
Clear all hooks for a service
Section titled “Clear all hooks for a service”DELETE /api/v1/containers/{id}/proxy/hooks/{service}
Delete every hook under the given service. Requires the If-Match header.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
if-match | header | string | Yes | file:v<N> ETag precondition |
curl -X DELETE \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/logs \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "If-Match: file:v42"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.clear( '890abcdef12345678901cdef', 'logs', { ifMatch: 'file:v42' });console.log(res.data);{ "statusCode": 200, "message": "Service hooks cleared successfully", "data": { "removed": 1, "file_version": 43, "etag": "file:v43" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 8, "action": "clear", "file_version": 43, "succeeded_count": 2, "failed_count": 0, "pending_count": 0, "target_count": 2, "retained_count": 2 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
{ "statusCode": 412, "error": "Precondition Failed", "message": "etag_mismatch"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 412 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 412 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 412 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 412 | The If-Match header does not match the current file_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"}{ "statusCode": 428, "error": "Precondition Required", "message": "If-Match header required for this operation"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 428 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 428 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 428 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 428 | The If-Match header does not match the current file_version |
Remove a hook
Section titled “Remove a hook”DELETE /api/v1/containers/{id}/proxy/hooks/{service}/{hookId}
Delete a single hook by its ULID. Requires the If-Match header.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
service | path | string | Yes | Service name |
hookId | path | string | Yes | 26-char Crockford base32 ULID (lowercase) |
if-match | header | string | Yes | file:v<N> ETag precondition |
curl -X DELETE \ https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef/proxy/hooks/api/01h8x3kq7v4mz0qy6f3t8n2rxd \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "If-Match: file:v42"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
const res = await client.api.proxy.hooks.delete( '890abcdef12345678901cdef', 'api', '01h8x3kq7v4mz0qy6f3t8n2rxd', { ifMatch: 'file:v42' });console.log(res.data);{ "statusCode": 200, "message": "Hook removed successfully", "data": { "file_version": 43, "etag": "file:v43" }, "propagation": { "committed": true, "complete": true, "state": "applied", "status_scope": "current", "generation": 8, "action": "remove", "file_version": 43, "succeeded_count": 2, "failed_count": 0, "pending_count": 0, "target_count": 2, "retained_count": 2 }}{ "statusCode": 404, "error": "Not Found", "message": "Resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
NOT_FOUND | Hook or service not found | The hook id, service, or container does not exist, or the service is reject-listed | Verify the service name is not a reserved service (such as logs, egress or cdp) and that the hook id exists |
VALIDATION_ERROR | Validation error | Request body violates hook schema, caps, or referential integrity | Check error details and correct the body shape; ensure applies_to.groups references defined groups |
PRECONDITION_REQUIRED | If-Match required | Destructive writes require an If-Match: file:v<N> header | Fetch the resource first to obtain the ETag and resend with If-Match |
PRECONDITION_FAILED | ETag mismatch | The If-Match header does not match the current file_version | Re-fetch the resource to get the current ETag and retry |
{ "statusCode": 412, "error": "Precondition Failed", "message": "etag_mismatch"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 412 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 412 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 412 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 412 | The If-Match header does not match the current file_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"}{ "statusCode": 428, "error": "Precondition Required", "message": "If-Match header required for this operation"}| Code | Status | Description |
|---|---|---|
NOT_FOUND | 428 | The hook id, service, or container does not exist, or the service is reject-listed |
VALIDATION_ERROR | 428 | Request body violates hook schema, caps, or referential integrity |
PRECONDITION_REQUIRED | 428 | Destructive writes require an If-Match: file:v<N> header |
PRECONDITION_FAILED | 428 | The If-Match header does not match the current file_version |