# Input and Output

Following is the gRPC API definition for the Rasa Action Server. The API is defined in the [`proto/action_webhook.proto`](https://github.com/RasaHQ/rasa-sdk/blob/main/proto/action_webhook.proto) file in the Rasa SDK repository.

## action_webhook.proto

```protobuf

syntax = "proto3";

package action_server_webhook;
import "google/protobuf/struct.proto";
import "google/protobuf/empty.proto";

service ActionService {
    rpc Webhook (WebhookRequest) returns (WebhookResponse);
    rpc WebhookStream (WebhookRequest) returns (stream WebhookStreamEvent);
    rpc AckStreamChunks (StreamChunkAck) returns (google.protobuf.Empty);
    rpc Actions (ActionsRequest) returns (ActionsResponse);
}

message WebhookStreamEvent {
  oneof event {
    ChunkStart chunk_start = 1;
    Chunk chunk = 2;
    ChunkEnd chunk_end = 3;
    WebhookResponse final_result = 4;
    StreamError error = 5;
  }
}

message ChunkStart { string response_id = 1; }

message Chunk {
    string response_id = 1;
    string text = 2;
    string image = 3;
    google.protobuf.Struct custom = 4;
    string attachment = 5;
    repeated google.protobuf.Struct buttons = 6;
    repeated google.protobuf.Struct elements = 7;
}

message ChunkEnd { string response_id = 1; }

message StreamError { string action_name = 1; string message = 2; }

message StreamChunkAck { string response_id = 1; }

message ActionsRequest {}

message ActionsResponse {
    repeated google.protobuf.Struct actions = 1;
}

message Tracker {
    string sender_id = 1;
    google.protobuf.Struct slots = 2;
    google.protobuf.Struct latest_message = 3;
    repeated google.protobuf.Struct events = 4;
    bool paused = 5;
    optional string followup_action = 6;
    map<string, string> active_loop = 7;
    optional string latest_action_name = 8;
    repeated google.protobuf.Struct stack = 9;
    optional string user_id = 10;
}

message Intent {
    string string_value = 1;
    google.protobuf.Struct dict_value = 2;
}

message Entity {
    string string_value = 1;
    google.protobuf.Struct dict_value = 2;
}

message Action {
    string string_value = 1;
    google.protobuf.Struct dict_value = 2;
}

message Domain {
    google.protobuf.Struct config = 1;
    google.protobuf.Struct session_config = 2;
    repeated Intent intents = 3;
    repeated Entity entities = 4;
    google.protobuf.Struct slots = 5;
    google.protobuf.Struct responses = 6;
    repeated Action actions = 7;
    google.protobuf.Struct forms = 8;
    repeated google.protobuf.Struct e2e_actions = 9;
}

message WebhookRequest {
    string next_action = 1;
    string sender_id = 2;
    Tracker tracker = 3;
    Domain domain = 4;
    string version = 5;
    optional string domain_digest = 6;
}

message WebhookResponse {
    repeated google.protobuf.Struct events = 1;
    repeated google.protobuf.Struct responses = 2;
}
```

## Streaming custom actions (`WebhookStream`)

New in Rasa SDK 3.17 / Rasa Pro 3.17

When Rasa executes a custom action on a streaming output channel and the action server is configured for gRPC, Rasa calls `WebhookStream` instead of the unary `Webhook` RPC.

The server streams `WebhookStreamEvent` messages in order:

| Event | Purpose |
| --- | --- |
| `chunk_start` | Opens a streaming response. Carries a `response_id` that correlates subsequent chunk events. |
| `chunk` | A single response fragment. The `Chunk` message carries `text`, `image`, `custom`, `attachment`, `buttons`, and `elements`. Only these fields are defined in the protobuf schema; extra keys are not transmitted. |
| `chunk_end` | Closes the streaming response for the given `response_id`. |
| `final_result` | Terminal event. Contains the same `events` and `responses` payload as a unary `WebhookResponse`. Must be the last event in the stream. |
| `error` | Action execution failed. Carries `action_name` and `message`. |

Rasa maps `chunk_start`, `chunk`, and `chunk_end` to the output channel's streaming methods (`send_response_chunk_start`, `send_response_chunk`, `send_response_chunk_end`).

### Barge-in (`AckStreamChunks`)

When a user interrupts a streaming custom action on a voice channel, Rasa sends a unary `AckStreamChunks` call with the active `response_id` from the in-flight stream. The action server calls `cancel_stream()` on the matching dispatcher so subsequent chunks are dropped, drains the action until it finishes naturally, and then yields `final_result` with any Rasa events the action returns.

If the action does not complete within the barge-in timeout (default 30 seconds, configurable via the `ACTION_SERVER_STREAM_BARGE_IN_TIMEOUT_SECONDS` environment variable on the action server), the SDK yields an empty `final_result` so Rasa can finish the barge-in handler and cancel a hung action.

## Error Handling

When Rasa server is communicating with the action server over gRPC protocol, and an error occurs, the action server should return appropriate error message containing proper gRPC status code and details.

Following are the possible error scenarios and the expected error response from the action server.

### Custom action is not found

In case that the action server does not find the custom action, it should return:

- an error with gRPC status code `NOT_FOUND`
- details in the error message in the format of:

```json
{
      "action_name" : { "type":  "string" },
      "message" : { "type": "string" },
      "resource_type" : "ACTION"
}
```

where `action_name` is the name of the action that was not found, `message` is a human-readable error message, and `resource_type` is the type of the resource that was not found.

### Custom action failed during execution

In case that the custom action fails during execution, it should return:

- an error with gRPC status code `INTERNAL`
- details in the error message in the format of:

```json
{
      "action_name" : { "type":  "string" },
      "message" : { "type": "string" }
}
```

where `action_name` is the name of the action that failed, and `message` is a human-readable error message.

### Domain is not found

In case that the action server does not find the domain, which corresponds to the [`domain_digest`](/content/docs/reference/integrations/action-server/actions/#domain_digest/index.html) of the assistant, it should return:

- an error with gRPC status code `NOT_FOUND`
- details in the error message in the format of:

```json
{
      "action_name" : { "type":  "string" },
      "message" : { "type": "string" },
      "resource_type" : "DOMAIN"
}
```

where `action_name` is the name of the action which was targeted for invocation, `message` is a human-readable error message, and `resource_type` is the type of the resource that was not found.
