Proxy hooks intercept container traffic before it reaches the real service backend. Each hook binds an HTTP match (method, path, and optional headers) to a script that runs inside the container proxy. Within a service, hooks are evaluated in declared order and the first match wins. All write operations are gated by an If-Match: file:v<N> ETag precondition that the API returns from any successful read; this prevents lost updates when concurrent writers operate on the same hook list.
Use these endpoints when you want to register, reorder, update, or remove MITM hook scripts for a specific service running inside a container.
Note
Hook ids are 26-character Crockford base32 ULIDs (lowercase, excluding i, l, o, u). Service names from the reject-list — logs, proxy, workspaces, cdp — cannot carry hooks.
Returns all hooks grouped by service for the given container, along with the current file_version and etag that subsequent writes must echo back.
Name In Type Required Description idpath string Yes Container ID
curl -X GET " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks " \
-H " Authorization: Bearer <token> "
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . listContainerProxyHooks ( containerId );
" message " : " Proxy hooks listed successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" content-type " : " application/json "
" path " : " /scripts/log-auth.js "
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
Returns the ordered hook array for a single service. Within a service the order is significant because evaluation is first-match-wins.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name
curl -X GET " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth " \
-H " Authorization: Bearer <token> "
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . listContainerProxyServiceHooks ( containerId , ' auth ' );
" message " : " Service hooks listed successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" path " : " /scripts/log-auth.js "
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h4 " ,
" path " : " /scripts/log-logout.js "
" groups " : [ " audit " , " observability " ]
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
Fetches a single hook by id within a service.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name hookIdpath string Yes 26-char Crockford base32 ULID (lowercase)
curl -X GET " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth/01h2x3y4z5a6b7c8d9e0f1g2h3 " \
-H " Authorization: Bearer <token> "
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . getContainerProxyHook ( containerId , ' auth ' , ' 01h2x3y4z5a6b7c8d9e0f1g2h3 ' );
" message " : " Hook retrieved successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" content-type " : " application/json "
" path " : " /scripts/log-auth.js "
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
Appends a new hook to the end of the service array, or inserts it at a specific position. Omit position to append. Requires an If-Match: file:v<N> header so that conflicting concurrent writers do not silently overwrite each other.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name if-matchheader string No file:v<N> ETag precondition
Field Type Required Description matchobject Yes HTTP match — method, path, and optional headers scriptobject Yes Script reference — path is required timeoutinteger No Hook execution budget in milliseconds (1-30000) applies_toobject No Restrict hook to specific groups positioninteger No 0-indexed insertion position (POST only)
curl -X POST " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
-H " If-Match: file:v42 " \
"headers": { "content-type": "application/json" }
"path": "/scripts/log-auth.js"
"applies_to": { "groups": ["audit"] }
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . addContainerProxyHook (
headers : { ' content-type ' : ' application/json ' }
path : ' /scripts/log-auth.js '
applies_to : { groups : [ ' audit ' ] }
" message " : " Hook created successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" path " : " /scripts/log-auth.js "
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
" error " : " Precondition Failed " ,
" message " : " etag_mismatch "
" error " : " Validation Error " ,
" message " : " Invalid hook "
" error " : " Precondition Required " ,
" message " : " If-Match header required for this operation "
Full-replaces a hook while preserving its id and position. Requires If-Match. The same path also accepts PATCH as a live alias, but the canonical verb is PUT.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name hookIdpath string Yes 26-char Crockford base32 ULID (lowercase) if-matchheader string No file:v<N> ETag precondition
Field Type Required Description matchobject Yes HTTP match — method, path, and optional headers scriptobject Yes Script reference — path is required timeoutinteger No Hook execution budget in milliseconds (1-30000) applies_toobject No Restrict hook to specific groups positioninteger No 0-indexed insertion position (POST only)
curl -X PUT " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth/01h2x3y4z5a6b7c8d9e0f1g2h3 " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
-H " If-Match: file:v43 " \
"path": "/v1/session/login",
"headers": { "content-type": "application/json" }
"path": "/scripts/log-session.js"
"applies_to": { "groups": ["audit", "observability"] }
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . updateContainerProxyHook (
' 01h2x3y4z5a6b7c8d9e0f1g2h3 ' ,
path : ' /v1/session/login ' ,
headers : { ' content-type ' : ' application/json ' }
path : ' /scripts/log-session.js '
applies_to : { groups : [ ' audit ' , ' observability ' ] }
" message " : " Hook replaced successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" path " : " /v1/session/login "
" path " : " /scripts/log-session.js "
" groups " : [ " audit " , " observability " ]
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
" error " : " Precondition Failed " ,
" message " : " etag_mismatch "
" error " : " Validation Error " ,
" message " : " Invalid hook "
" error " : " Precondition Required " ,
" message " : " If-Match header required for this operation "
Performs an atomic move of a hook within its service array. The body is { position: N }. Requires If-Match.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name hookIdpath string Yes 26-char Crockford base32 ULID (lowercase) if-matchheader string No file:v<N> ETag precondition
Field Type Required Description positioninteger Yes 0-indexed target position in the service array
curl -X PATCH " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth/01h2x3y4z5a6b7c8d9e0f1g2h3/position " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
-H " If-Match: file:v44 " \
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . moveContainerProxyHook (
' 01h2x3y4z5a6b7c8d9e0f1g2h3 ' ,
" message " : " Hook moved successfully " ,
" id " : " 01h2x3y4z5a6b7c8d9e0f1g2h3 " ,
" path " : " /v1/session/login "
" path " : " /scripts/log-session.js "
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
" error " : " Precondition Failed " ,
" message " : " etag_mismatch "
" error " : " Precondition Required " ,
" message " : " If-Match header required for this operation "
Removes every hook under the named service. Returns the count of hooks removed and the new etag. Requires If-Match.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name if-matchheader string No file:v<N> ETag precondition
This endpoint takes no request body.
curl -X DELETE " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth " \
-H " Authorization: Bearer <token> " \
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . clearContainerProxyServiceHooks ( containerId , ' auth ' , { ifMatch : ' file:v45 ' });
" message " : " Service hooks cleared successfully " ,
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
" error " : " Precondition Failed " ,
" message " : " etag_mismatch "
" error " : " Precondition Required " ,
" message " : " If-Match header required for this operation "
Removes a single hook. The service’s remaining hooks retain their existing positions. Requires If-Match.
Name In Type Required Description idpath string Yes Container ID servicepath string Yes Service name hookIdpath string Yes 26-char Crockford base32 ULID (lowercase) if-matchheader string No file:v<N> ETag precondition
This endpoint takes no request body.
curl -X DELETE " https://api.hoody.com/api/v1/containers/{containerId}/proxy/hooks/auth/01h2x3y4z5a6b7c8d9e0f1g2h3 " \
-H " Authorization: Bearer <token> " \
import { HoodyClient } from ' hoody-sdk ' ;
const client = new HoodyClient ({ baseURL : ' https://api.hoody.com ' , token : process . env . HOODY_TOKEN });
await client . api . proxyHooks . removeContainerProxyHook (
' 01h2x3y4z5a6b7c8d9e0f1g2h3 ' ,
" message " : " Hook removed successfully " ,
" message " : " Resource not found "
Error Code Title Description Resolution NOT_FOUNDHook 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 reject-listed (logs, proxy, workspaces, cdp) and that the hook id exists VALIDATION_ERRORValidation 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_REQUIREDIf-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_FAILEDETag mismatch The If-Match header does not match the current file_version Re-fetch the resource to get the current ETag and retry
" error " : " Precondition Failed " ,
" message " : " etag_mismatch "
" error " : " Precondition Required " ,
" message " : " If-Match header required for this operation "