External service policy API reference
This feature is in Beta. Workspace admins can control access to this feature from the Previews page by opting into the Unity Gateway Service Policies preview. See Manage workspace-level previews.
When a customer attaches an external service policy to a service, Unity Gateway calls a guardrail vendor's HTTP endpoint on each governed interaction and enforces the verdict that the endpoint returns. This page describes the contract that the endpoint implements: the request Databricks sends, the response it expects, and how it handles each response.
Use this page to build an endpoint that customers can use with external service policies, or to check that a vendor's endpoint is compatible. For the customer setup, see Enforce a partner guardrail with an external service policy.
How it works
On each governed interaction, Databricks sends a POST request with a JSON body to the endpoint. The endpoint inspects the content and returns ALLOW, DENY, or, for an MCP tool call, ASK, and Databricks enforces the verdict.
One endpoint can serve many customers and policies. A customer chooses the behavior they want with the policy configuration, which Databricks passes to the endpoint on every request.
Endpoint requirements
The endpoint must:
- Accept
POSTrequests with a JSON body at the host and path that the customer configures on the connection. - Accept OAuth machine-to-machine (M2M) authentication. The customer configures a client ID, a client secret, your token endpoint, and optional scopes on the connection. Databricks gets an access token from your token endpoint and sends it in the
Authorizationheader of each request. Your token endpoint must return tokens in the format the OAuth 2.0 specification defines. See External services must comply with OAuth 2.0 specifications. - Use HTTPS. Databricks doesn't call an endpoint over plain HTTP.
- Respond within 5 seconds. Databricks denies the interaction when the endpoint doesn't respond in time.
- Return HTTP
200with a JSON verdict for every decision, including a block, in a response body no larger than 64 KB.
If the endpoint supports more than one behavior, such as different detection profiles, tell customers what to enter as the policy configuration.
Request
Databricks sends each evaluation as an HTTP request to the connection's host and path. The path is / when the connection has none.
POST /<path> HTTP/1.1
Host: <host>
Authorization: Bearer <access-token>
Content-Type: application/json
The body is a JSON object with two members:
{
"event": {},
"config": {}
}
eventis the interaction under evaluation. See Theeventobject.configholds the policy's options, including the customer's policy configuration. See Theconfigobject.
The event object
Field | Type | Description |
|---|---|---|
| String | The interaction and phase: |
| String | The three-level name of the governed service in Unity Catalog, for example |
| Object | The content under evaluation. Its shape depends on |
| Object | The originating request, so you can judge a result in the context of its request. Present on |
| String | The API format of |
| String | The OpenTelemetry trace ID of the governed request. Use it to match an evaluation in your logs to the request. Present only when the request has a trace, so don't require it. |
The event carries content only. It doesn't include the identity of the user, agent, or app that made the call.
Event types
| Service and phase |
|
|
|---|---|---|---|
| MCP Service, before the tool runs |
| Not present |
| MCP Service, after the tool runs | The tool's result |
|
| Model Service or Model Provider Service, before the model is called | The full model request body, in the format named by | Not present |
| Model Service or Model Provider Service, after the model responds | The full model response body, in the format named by | The full model request body |
A model request body includes the messages in the request, such as the system prompt and earlier turns of the conversation. If the customer sets a conversation window for the policy, the body can hold only the most recent messages, so don't assume that the full conversation is present.
API types
Model events carry the request and response bodies in the API format that the caller used. Databricks doesn't convert them to a common format. The api_type field names the format:
| Format |
|---|---|
| Databricks chat completions, compatible with OpenAI Chat Completions |
| Databricks completions |
| Databricks embeddings |
| Databricks Open Responses |
| OpenAI Chat Completions |
| OpenAI Completions |
| OpenAI Embeddings |
| OpenAI Responses |
| Anthropic Messages |
| Gemini |
| Gemini |
| Cursor chat completions |
| Codex Responses |
|
Unity Gateway can add API types as it supports more APIs. Treat an api_type you don't recognize as content you can't parse, and return a deliberate verdict for it, such as DENY.
The config object
config holds the policy's options as strings. It doesn't include the connection or path.
Field | Type | Description |
|---|---|---|
| String | The policy configuration exactly as the customer entered it, as a JSON object passed in a string. Parse the string as JSON, for example |
| String | The phases the policy runs on: |
config can include other policy options. Ignore keys you don't recognize.
Request examples
An MCP tool call, before the tool runs:
{
"event": {
"type": "tool_call",
"target": "main.default.github_mcp",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"data": {
"name": "create_issue",
"arguments": { "repo": "acme/website", "title": "Bug: checkout returns 500" }
}
},
"config": {
"policy_config": "{\"profile\": \"strict\"}",
"phases": "pre_call"
}
}
An MCP tool result, after the tool runs:
{
"event": {
"type": "tool_result",
"target": "main.default.github_mcp",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"data": { "content": [{ "type": "text", "text": "Issue #4213 created" }] },
"request_data": { "name": "create_issue", "arguments": { "repo": "acme/website" } }
},
"config": {
"phases": "pre_call,post_call"
}
}
A model request, before the model is called:
{
"event": {
"type": "model_call",
"target": "main.default.support_assistant",
"api_type": "mlflow/v1/chat/completions",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"data": {
"messages": [
{ "role": "system", "content": "You are a support agent." },
{ "role": "user", "content": "My card number is 4111 1111 1111 1111. Please refund me." }
],
"max_tokens": 512
}
},
"config": {
"phases": "pre_call"
}
}
A model response, after the model responds:
{
"event": {
"type": "model_result",
"target": "main.default.support_assistant",
"api_type": "mlflow/v1/chat/completions",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"data": { "choices": [{ "message": { "role": "assistant", "content": "Here is your refund link." } }] },
"request_data": { "messages": [{ "role": "user", "content": "Please refund me." }] }
},
"config": {
"phases": "post_call"
}
}
Response
Return HTTP 200 with a JSON body:
{
"result": "DENY",
"reason": "The message contains a payment card number."
}
Field | Type | Description |
|---|---|---|
| String | Required. |
| String | Optional. On |
Return a block as a DENY verdict with HTTP 200, not as an HTTP error. Databricks treats an HTTP error as a failed evaluation, so it denies the interaction, but the caller doesn't see your reason.
External service policies can't redact or rewrite content, so don't return a modified payload.
Hold a tool call for approval
On a tool_call event, return ASK to hold the tool call until the user approves it. If the user approves, Databricks runs the tool call. Return ASK only for a tool_call event:
- On a
tool_resultevent,ASKdoesn't block. The result goes through as if you returnedALLOW. To block a result, returnDENY. - On a
model_callormodel_resultevent, Databricks blocks the interaction, because Model Services and Model Provider Services can't ask the user for approval.
How Databricks handles each response
External service policies fail closed. Databricks denies the interaction whenever it can't read a verdict from the endpoint:
Response | What Databricks does |
|---|---|
| Allows the interaction. |
| Denies the interaction and returns your |
| On a |
| Denies the interaction. |
The body isn't valid JSON, or it has a top-level | Denies the interaction. |
The body is larger than 64 KB | Denies the interaction. |
The HTTP status isn't 2xx | Denies the interaction. |
No response within 5 seconds | Denies the interaction. |
The connection fails | Denies the interaction. |
Customers can't configure an external service policy to allow traffic when the endpoint fails.
When Databricks calls the endpoint
- Databricks calls the endpoint one time for each phase the policy runs on: before the service is called, after it responds, or both. A policy that runs on both phases sends two requests for each interaction.
- When the customer attaches the policy in Log mode, Databricks still calls the endpoint and records your verdict, but doesn't enforce it.
- A
DENYfrom another policy that runs before the external service policy can stop the interaction before Databricks calls your endpoint. See Order of evaluation.
Data handling
Each request carries customer content: model request and response bodies, including system prompts and earlier messages, and MCP tool names, arguments, and results. Handle it as customer data, and document for customers what your endpoint stores, for how long, and where it processes the content.
Test your endpoint
Before customers use your endpoint, send it a sample request and check that it returns HTTP 200 with a result of ALLOW, DENY, or ASK in under 5 seconds:
curl -X POST "https://api.example.com/ai-security/v1" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"event": {"type": "tool_call", "target": "main.default.github_mcp", "data": {"name": "create_issue", "arguments": {"repo": "acme/website"}}}, "config": {"policy_config": "{\"profile\": \"strict\"}", "phases": "pre_call"}}'
To test the full flow, attach an external service policy that uses your endpoint to a service in a Databricks workspace, in Log mode, and review the recorded verdicts in the unified trace table. See Enforce a partner guardrail with an external service policy.