Manage OpenWAF Egress, the gateway between your AI agents and their providers, with targets, credentials, agents and events.
OpenWAF Egress sits between your AI agents and their providers. Agents call the gateway with a substitute token, and the gateway adds the real provider credential, inspects the request and blocks injections, data leaks and disallowed destinations. Reads need the readonly role and writes admin, both organization-wide; creating and changing agents, targets and credentials and reading events require the egress feature to be enabled for the organization (otherwise 403 feature_disabled). See OpenWAF Egress .
# Get egress status
GET /v1/orgs/{org}/egress
Returns the egress status of the organization. It can be read without the egress feature (enabled false). Without the feature, reading and deleting agents, targets and credentials keeps working so the organization can remove its keys.
Required role: readonly or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404).
# Response
Field Type Description enabledboolean The organization has the egress feature. gateway_urlstring credentials_availableboolean Credentials can be stored right now.
# Errors
Status Description 403The token's role or limits do not allow it (forbidden).
# Example
curl TypeScript Python
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.getEgress();from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.get_egress()
200
{
"enabled" : false ,
"gateway_url" : "https://egress.openwaf.dev" ,
"credentials_available" : false
}
# List targets
GET /v1/orgs/{org}/egress/targets
Lists the egress targets, the catalog providers and your own, with the status of their credential.
Required role: readonly or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404).
# Response
Field Type Description items[].idstring Id. items[].namestring Name. items[].base_urlstring items[].hoststring items[].auth_headerstring items[].auth_prefixstring items[].customboolean Own target of the organization (false = catalog). items[].docs_urlstring items[].credentialEgressCredential
# Errors
Status Description 403The token's role or limits do not allow it (forbidden).
# Example
curl TypeScript Python
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/targets" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.listEgressTargets();from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.list_egress_targets()
200
{
"items" : [
{
"id" : "openrouter" ,
"name" : "example.com" ,
"base_url" : "https://llm.example.com/v1" ,
"host" : "www.example.com" ,
"auth_header" : "Authorization" ,
"auth_prefix" : "Bearer " ,
"custom" : false ,
"docs_url" : "https://platform.openai.com/docs/api-reference" ,
"credential" : {
"fingerprint" : "sha256:3f9a1c2b7d4e" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"updated_by" : "token:11111111-2222-4333-8444-555555555555"
}
}
]
}
# Create target
POST /v1/orgs/{org}/egress/targets
Creates an own HTTPS target. base_url must be https:// on port 443 with a public DNS name (no IP address, user, query or fragment). On every request the gateway also checks that the name only resolves to public addresses (ssrf_blocked).
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404).
# Request body
Content type application/json.
Field Type Required Description idstring Yes Cannot be a catalog id. Pattern ^[a-z][a-z0-9-]{1,31}$. namestring Yes Name. 1 to 100 characters. base_urlstring Yes At most 2048 characters. auth_headerstring No Default Authorization. Pattern ^[A-Za-z0-9-]{1,64}$. auth_prefixstring No Bearer by default with Authorization, empty with other headers. At most 32 characters.
# Response
Field Type Description idstring Id. namestring Name. base_urlstring hoststring auth_headerstring auth_prefixstring customboolean Own target of the organization (false = catalog). docs_urlstring credentialEgressCredential
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 409The current state does not allow it (conflict). 422Validation error (invalid).
# Example
curl TypeScript Python
curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/targets" \
-H "Authorization: Bearer $OPENWAF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"id" : "internal-llm" ,
"name" : "Internal LLM" ,
"base_url" : "https://llm.example.com/v1"
}'import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.createEgressTarget({
body: {
id: "internal-llm" ,
name: "Internal LLM" ,
base_url: "https://llm.example.com/v1"
}
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.create_egress_target(
body={
"id" : "internal-llm" ,
"name" : "Internal LLM" ,
"base_url" : "https://llm.example.com/v1"
},
)
201
{
"id" : "openrouter" ,
"name" : "example.com" ,
"base_url" : "https://llm.example.com/v1" ,
"host" : "www.example.com" ,
"auth_header" : "Authorization" ,
"auth_prefix" : "Bearer " ,
"custom" : false ,
"docs_url" : "https://platform.openai.com/docs/api-reference" ,
"credential" : {
"fingerprint" : "sha256:3f9a1c2b7d4e" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"updated_by" : "token:11111111-2222-4333-8444-555555555555"
}
}
# Delete target
DELETE /v1/orgs/{org}/egress/targets/{target}
Deletes an own target and its credential. Catalog targets cannot be deleted.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). targetpath string Yes Egress target id: a catalog id such as openai or the id of an own target. Pattern ^[a-z][a-z0-9-]{1,31}$.
# Response
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found). 409target_in_use: some agent allows it.422invalid: catalog targets cannot be deleted.
# Example
curl TypeScript Python
curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/targets/openai" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.deleteEgressTarget({
target: "openai"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.delete_egress_target(target="openai" )
# Set target credential
PUT /v1/orgs/{org}/egress/targets/{target}/credential
Stores or replaces the provider credential of a target. It is write-only, kept in a dedicated secret store, never logged and never returned; the answer only carries its fingerprint (sha256: and 12 hexadecimal characters).
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). targetpath string Yes Egress target id: a catalog id such as openai or the id of an own target. Pattern ^[a-z][a-z0-9-]{1,31}$.
# Request body
Content type application/json.
Field Type Required Description secretstring Yes 1 to 8192 characters.
# Response
Field Type Description idstring Id. namestring Name. base_urlstring hoststring auth_headerstring auth_prefixstring customboolean Own target of the organization (false = catalog). docs_urlstring credentialEgressCredential
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found). 422Validation error (invalid). 502A dependency refused or did not answer; retry later. 503Not available right now (unavailable); retry later.
# Example
curl TypeScript Python
curl -X PUT "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/targets/openai/credential" \
-H "Authorization: Bearer $OPENWAF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"secret" : "sk-…"
}'import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.putEgressCredential({
target: "openai" ,
body: {
secret: "sk-…"
}
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.put_egress_credential(
target="openai" ,
body={
"secret" : "sk-…"
},
)
200
{
"id" : "openrouter" ,
"name" : "example.com" ,
"base_url" : "https://llm.example.com/v1" ,
"host" : "www.example.com" ,
"auth_header" : "Authorization" ,
"auth_prefix" : "Bearer " ,
"custom" : false ,
"docs_url" : "https://platform.openai.com/docs/api-reference" ,
"credential" : {
"fingerprint" : "sha256:3f9a1c2b7d4e" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"updated_by" : "token:11111111-2222-4333-8444-555555555555"
}
}
# Delete target credential
DELETE /v1/orgs/{org}/egress/targets/{target}/credential
Deletes the provider credential of a target, every stored version. Idempotent; it also works without the egress feature.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). targetpath string Yes Egress target id: a catalog id such as openai or the id of an own target. Pattern ^[a-z][a-z0-9-]{1,31}$.
# Response
204: Deleted (or did not exist). No body.
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found). 502A dependency refused or did not answer; retry later. 503Not available right now (unavailable); retry later.
# Example
curl TypeScript Python
curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/targets/openai/credential" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.deleteEgressCredential({
target: "openai"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.delete_egress_credential(target="openai" )
# List agents
GET /v1/orgs/{org}/egress/agents
Lists the egress agents of the organization.
Required role: readonly or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404).
# Response
Field Type Description items[].idstring (uuid) Id. items[].namestring Name. items[].descriptionstring items[].allowed_targetsarray of string items[].enforce_injectionboolean items[].block_dlpboolean items[].disabledboolean items[].token_prefixstring Start of the token (OWE_TOKEN_ and 6 characters), to recognise it. items[].token_rotated_atstring (date-time) items[].created_atstring (date-time) Creation time. items[].created_bystring Who created it (actor). items[].updated_atstring (date-time) Last change. items[].base_urlsmap of string SDK base URL for each allowed target.
# Errors
Status Description 403The token's role or limits do not allow it (forbidden).
# Example
curl TypeScript Python
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.listEgressAgents();from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.list_egress_agents()
200
{
"items" : [
{
"id" : "a5614527-0ce6-43be-ad1d-d012b7394867" ,
"name" : "example.com" ,
"description" : "Support assistant" ,
"allowed_targets" : [
"openai"
],
"enforce_injection" : false ,
"block_dlp" : false ,
"disabled" : false ,
"token_prefix" : "OWE_TOKEN_ab12cd" ,
"token_rotated_at" : "2026-10-27T09:30:00Z" ,
"created_at" : "2026-10-27T09:30:00Z" ,
"created_by" : "token:11111111-2222-4333-8444-555555555555" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"base_urls" : {
"openrouter" : "https://egress.openwaf.dev/v1/agent/support-bot/proxy/openrouter"
}
}
]
}
# Create agent
POST /v1/orgs/{org}/egress/agents
Creates an agent allowed to call some targets through the gateway. Its substitute token is returned only in this answer. name is part of the agent's gateway URLs and cannot change.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404).
# Request body
Content type application/json.
Field Type Required Description namestring Yes Unique in the organization; part of its gateway URLs and cannot change. Pattern ^[a-z0-9][a-z0-9-]{0,62}$. descriptionstring No At most 500 characters. allowed_targetsarray of string Yes 1 to 32 items. enforce_injectionboolean No Default true. block_dlpboolean No Default true. disabledboolean No Default false.
# Response
Field Type Description agentEgressAgent tokenstring Substitute token OWE_TOKEN_…; shown only once (only its SHA-256 is stored).
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 409The current state does not allow it (conflict). 422Validation error (invalid).
# Example
curl TypeScript Python
curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents" \
-H "Authorization: Bearer $OPENWAF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"name" : "support-bot" ,
"allowed_targets" : [
"openai"
]
}'import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.createEgressAgent({
body: {
name: "support-bot" ,
allowed_targets: [
"openai"
]
}
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.create_egress_agent(
body={
"name" : "support-bot" ,
"allowed_targets" : [
"openai"
]
},
)
201
{
"agent" : {
"id" : "a5614527-0ce6-43be-ad1d-d012b7394867" ,
"name" : "example.com" ,
"description" : "Support assistant" ,
"allowed_targets" : [
"openai"
],
"enforce_injection" : false ,
"block_dlp" : false ,
"disabled" : false ,
"token_prefix" : "OWE_TOKEN_ab12cd" ,
"token_rotated_at" : "2026-10-27T09:30:00Z" ,
"created_at" : "2026-10-27T09:30:00Z" ,
"created_by" : "token:11111111-2222-4333-8444-555555555555" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"base_urls" : {
"openrouter" : "https://egress.openwaf.dev/v1/agent/support-bot/proxy/openrouter"
}
},
"token" : "owf_…"
}
# Get agent
GET /v1/orgs/{org}/egress/agents/{agent}
Returns one egress agent.
Required role: readonly or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). agentpath string (uuid) Yes Egress agent id.
# Response
Field Type Description idstring (uuid) Id. namestring Name. descriptionstring allowed_targetsarray of string enforce_injectionboolean block_dlpboolean disabledboolean token_prefixstring Start of the token (OWE_TOKEN_ and 6 characters), to recognise it. token_rotated_atstring (date-time) created_atstring (date-time) Creation time. created_bystring Who created it (actor). updated_atstring (date-time) Last change. base_urlsmap of string SDK base URL for each allowed target.
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found).
# Example
curl TypeScript Python
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents/4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.getEgressAgent({
agent: "4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.get_egress_agent(agent="4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" )
200
{
"id" : "a5614527-0ce6-43be-ad1d-d012b7394867" ,
"name" : "example.com" ,
"description" : "Support assistant" ,
"allowed_targets" : [
"openai"
],
"enforce_injection" : false ,
"block_dlp" : false ,
"disabled" : false ,
"token_prefix" : "OWE_TOKEN_ab12cd" ,
"token_rotated_at" : "2026-10-27T09:30:00Z" ,
"created_at" : "2026-10-27T09:30:00Z" ,
"created_by" : "token:11111111-2222-4333-8444-555555555555" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"base_urls" : {
"openrouter" : "https://egress.openwaf.dev/v1/agent/support-bot/proxy/openrouter"
}
}
# Update agent
PATCH /v1/orgs/{org}/egress/agents/{agent}
Changes an agent. Fields left out keep their value; the name cannot change.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). agentpath string (uuid) Yes Egress agent id.
# Request body
Content type application/json.
Field Type Required Description descriptionstring No At most 500 characters. allowed_targetsarray of string No 1 to 32 items. enforce_injectionboolean No block_dlpboolean No disabledboolean No
# Response
Field Type Description idstring (uuid) Id. namestring Name. descriptionstring allowed_targetsarray of string enforce_injectionboolean block_dlpboolean disabledboolean token_prefixstring Start of the token (OWE_TOKEN_ and 6 characters), to recognise it. token_rotated_atstring (date-time) created_atstring (date-time) Creation time. created_bystring Who created it (actor). updated_atstring (date-time) Last change. base_urlsmap of string SDK base URL for each allowed target.
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found). 422Validation error (invalid).
# Example
curl TypeScript Python
curl -X PATCH "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents/4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" \
-H "Authorization: Bearer $OPENWAF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"allowed_targets" : [
"openai" ,
"anthropic"
]
}'import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.updateEgressAgent({
agent: "4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" ,
body: {
allowed_targets: [
"openai" ,
"anthropic"
]
}
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.update_egress_agent(
agent="4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" ,
body={
"allowed_targets" : [
"openai" ,
"anthropic"
]
},
)
200
{
"id" : "a5614527-0ce6-43be-ad1d-d012b7394867" ,
"name" : "example.com" ,
"description" : "Support assistant" ,
"allowed_targets" : [
"openai"
],
"enforce_injection" : false ,
"block_dlp" : false ,
"disabled" : false ,
"token_prefix" : "OWE_TOKEN_ab12cd" ,
"token_rotated_at" : "2026-10-27T09:30:00Z" ,
"created_at" : "2026-10-27T09:30:00Z" ,
"created_by" : "token:11111111-2222-4333-8444-555555555555" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"base_urls" : {
"openrouter" : "https://egress.openwaf.dev/v1/agent/support-bot/proxy/openrouter"
}
}
# Delete agent
DELETE /v1/orgs/{org}/egress/agents/{agent}
Deletes an egress agent; its token stops working.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). agentpath string (uuid) Yes Egress agent id.
# Response
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found).
# Example
curl TypeScript Python
curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents/4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.deleteEgressAgent({
agent: "4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.delete_egress_agent(agent="4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" )
# Rotate agent token
POST /v1/orgs/{org}/egress/agents/{agent}/rotate-token
Gives the agent a new substitute token, returned only in this answer. The previous one stops working as soon as the gateways load the new configuration.
Required role: admin or higher. Organization-wide.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). agentpath string (uuid) Yes Egress agent id.
# Response
Field Type Description agentEgressAgent tokenstring Substitute token OWE_TOKEN_…; shown only once (only its SHA-256 is stored).
# Errors
Status Description 403The token's role or limits do not allow it (forbidden). 404Not found, or not visible to the token (not_found).
# Example
curl TypeScript Python
curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/agents/4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c/rotate-token" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.rotateEgressAgentToken({
agent: "4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.rotate_egress_agent_token(agent="4a2c6e8b-0d1f-4c3e-9b5a-7d9f1b3e5a7c" )
200
{
"agent" : {
"id" : "a5614527-0ce6-43be-ad1d-d012b7394867" ,
"name" : "example.com" ,
"description" : "Support assistant" ,
"allowed_targets" : [
"openai"
],
"enforce_injection" : false ,
"block_dlp" : false ,
"disabled" : false ,
"token_prefix" : "OWE_TOKEN_ab12cd" ,
"token_rotated_at" : "2026-10-27T09:30:00Z" ,
"created_at" : "2026-10-27T09:30:00Z" ,
"created_by" : "token:11111111-2222-4333-8444-555555555555" ,
"updated_at" : "2026-10-27T09:30:00Z" ,
"base_urls" : {
"openrouter" : "https://egress.openwaf.dev/v1/agent/support-bot/proxy/openrouter"
}
},
"token" : "owf_…"
}
# List egress events
GET /v1/orgs/{org}/egress/events
Lists the requests blocked by the egress gateway, newest first, with the same filters and shape as List events . Each block is an event with action block, attack_type egress, the code in rule_name (injection_detected, data_leak_blocked, ssrf_blocked, egress_blocked, body_too_large), the target in host, the agent name in user_agent and the detection ids in msg. The request body is never included.
Required role: readonly or higher. Organization-wide. Needs the egress feature.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). sincequery string (date-time) No RFC 3339; until minus 24 hours by default. untilquery string (date-time) No RFC 3339, exclusive; now by default. At most 31 days of range. actionquery string No Repeatable (any of the values, at most 20). One of block, log, challenge, allow. ipquery string No IPv4 or IPv6 (normalized); repeatable. hostquery string No Exact name (case-insensitive); repeatable. 1 to 253 characters. pathquery string No Exact path (1-2048 bytes); repeatable. 1 to 2048 characters. statusquery integer No HTTP status of the response; repeatable. From 100 to 599. rule_namequery string No Exact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters. not_actionquery string No Excludes those actions; repeatable. One of block, log, challenge, allow. not_ipquery string No Excludes those IPs; repeatable. not_hostquery string No Excludes those names; repeatable. 1 to 253 characters. not_pathquery string No Excludes those exact paths; repeatable. 1 to 2048 characters. not_statusquery integer No Excludes those HTTP statuses; repeatable. From 100 to 599. not_rule_namequery string No Excludes those rule_name values; repeatable. 1 to 200 characters. qquery string No Free text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters. limitquery integer No Maximum number of items. Default 100. From 1 to 1000. cursorquery string No next_cursor of the previous page.
# Response
200: Returns an object with the fields below.
Field Type Description itemsarray of EdgeEvent next_cursorstring
# Errors
Status Description 400Malformed request (bad_request). 403The token's role or limits do not allow it (forbidden). 503Not available right now (unavailable); retry later.
# Example
curl TypeScript Python
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/events?rule_name=injection_detected" \
-H "Authorization: Bearer $OPENWAF_TOKEN" import { OpenWAF } from "./openwaf" ;
const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token from OPENWAF_TOKEN
const result = await owf.listEgressEvents({
rule_name: "injection_detected"
});from openwaf import OpenWAF
owf = OpenWAF(base_url="https://dash.openwaf.dev" ) # token from OPENWAF_TOKEN
result = owf.list_egress_events(rule_name="injection_detected" )
200
{
"items" : [
{
"event_id" : "8b3e5f7a-1c2d-4e6f-9a0b-3c5d7e9f1a2b" ,
"zone_id" : "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d" ,
"node_id" : "edge-node" ,
"ts" : "2026-10-27T09:29:58Z" ,
"host" : "www.example.com" ,
"ip" : "203.0.113.10" ,
"method" : "POST" ,
"path" : "/login" ,
"status" : 429 ,
"action" : "block" ,
"rule_id" : 0 ,
"rule_name" : "rate_rule:login" ,
"attack_type" : "rate_limit" ,
"msg" : "" ,
"country_code" : "ES" ,
"asn" : 64500 ,
"user_agent" : "Mozilla/5.0" ,
"tls_fingerprint" : "" ,
"received_at" : "2026-10-27T09:29:59Z" ,
"rate_rule" : "login"
}
],
"next_cursor" : ""
}
# Stream egress events
GET /v1/orgs/{org}/egress/events/stream
Streams the egress gateway blocks as Server-Sent Events, with the same frames, resumption and limits as Stream events and the events of List egress events .
Required role: readonly or higher. Organization-wide. Needs the egress feature.
# Parameters
Name In Type Required Description orgpath string (uuid) Yes Organization id. Every route checks that it is the token's organization (otherwise 404). Last-Event-IDheader string No id of the last event received from a stream; takes precedence over cursor.cursorquery string No id of an event of a previous stream: starts right after it.actionquery string No Repeatable (any of the values, at most 20). One of block, log, challenge, allow. ipquery string No IPv4 or IPv6 (normalized); repeatable. hostquery string No Exact name (case-insensitive); repeatable. 1 to 253 characters. pathquery string No Exact path (1-2048 bytes); repeatable. 1 to 2048 characters. statusquery integer No HTTP status of the response; repeatable. From 100 to 599. rule_namequery string No Exact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters. not_actionquery string No Excludes those actions; repeatable. One of block, log, challenge, allow. not_ipquery string No Excludes those IPs; repeatable. not_hostquery string No Excludes those names; repeatable. 1 to 253 characters. not_pathquery string No Excludes those exact paths; repeatable. 1 to 2048 characters. not_statusquery integer No Excludes those HTTP statuses; repeatable. From 100 to 599. not_rule_namequery string No Excludes those rule_name values; repeatable. 1 to 200 characters. qquery string No Free text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters.
# Response
200: Server-Sent Events stream. Body of type text/event-stream.
# Errors
Status Description 400Malformed request (bad_request). 403The token's role or limits do not allow it (forbidden). 429Too many requests (rate_limited); wait Retry-After seconds. 503Not available right now (unavailable); retry later.
# Example
Not in the SDKs: open the stream with EventSource or any Server-Sent Events client.
curl -N "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/egress/events/stream" \
-H "Authorization: Bearer $OPENWAF_TOKEN"