> ## Documentation Index
> Fetch the complete documentation index at: https://docs.evo-ai.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks & Agent Info

> Configure push notifications and retrieve agent metadata for A2A integrations

## Overview

These endpoints allow you to configure push notifications (webhooks) for asynchronous task updates and retrieve detailed agent information for better integration planning.

<Note>
  **Push Notifications**: Webhooks enable real-time notifications about task status changes, perfect for long-running operations where polling isn't efficient.
</Note>

***

## tasks/pushNotificationConfig/set

Configure webhook endpoints to receive push notifications about task status changes.

### Request Parameters

<ParamField body="jsonrpc" type="string" required>
  JSON-RPC version, must be `"2.0"`
</ParamField>

<ParamField body="id" type="string" required>
  Unique identifier for this request
</ParamField>

<ParamField body="method" type="string" required>
  Must be `"tasks/pushNotificationConfig/set"`
</ParamField>

<ParamField body="params" type="object" required>
  Webhook configuration parameters

  <Expandable title="params properties">
    <ParamField body="params.config" type="object" required>
      Webhook configuration object

      <Expandable title="config properties">
        <ParamField body="params.config.url" type="string" required>
          Webhook endpoint URL that will receive notifications
        </ParamField>

        <ParamField body="params.config.headers" type="object">
          Optional HTTP headers to include in webhook requests
        </ParamField>

        <ParamField body="params.config.events" type="array">
          Array of events to subscribe to (default: all events)

          Options: `["task.submitted", "task.working", "task.completed", "task.failed", "task.canceled"]`
        </ParamField>

        <ParamField body="params.config.retryPolicy" type="object">
          Retry configuration for failed webhook deliveries

          <Expandable title="retryPolicy properties">
            <ParamField body="params.config.retryPolicy.maxRetries" type="number">
              Maximum number of retry attempts (default: 3)
            </ParamField>

            <ParamField body="params.config.retryPolicy.backoffMultiplier" type="number">
              Exponential backoff multiplier (default: 2.0)
            </ParamField>

            <ParamField body="params.config.retryPolicy.initialDelay" type="number">
              Initial delay in seconds (default: 1)
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="params.config.secret" type="string">
          Secret for webhook signature verification (HMAC-SHA256)
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="params.taskId" type="string">
      Optional: Configure webhooks for specific task only
    </ParamField>
  </Expandable>
</ParamField>

### Response

<ResponseField name="jsonrpc" type="string">
  JSON-RPC version, always `"2.0"`
</ResponseField>

<ResponseField name="result" type="object">
  Configuration result

  <Expandable title="result properties">
    <ResponseField name="result.configured" type="boolean">
      Whether webhook was successfully configured
    </ResponseField>

    <ResponseField name="result.configId" type="string">
      Unique identifier for this webhook configuration
    </ResponseField>

    <ResponseField name="result.url" type="string">
      Configured webhook URL
    </ResponseField>

    <ResponseField name="result.events" type="array">
      List of subscribed events
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "http://localhost:8000/api/v1/a2a/my-agent" \
    -H "Content-Type: application/json" \
    -H "x-api-key: your-api-key" \
    -d '{
      "jsonrpc": "2.0",
      "id": "req-webhook-config",
      "method": "tasks/pushNotificationConfig/set",
      "params": {
        "config": {
          "url": "https://your-server.com/webhook/a2a",
          "headers": {
            "Authorization": "Bearer webhook-token",
            "X-Webhook-Source": "evo-ai"
          },
          "events": ["task.completed", "task.failed"],
          "retryPolicy": {
            "maxRetries": 5,
            "backoffMultiplier": 2.0,
            "initialDelay": 2
          },
          "secret": "your-webhook-secret"
        }
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://localhost:8000/api/v1/a2a/my-agent', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'your-api-key'
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "req-webhook-config",
      method: "tasks/pushNotificationConfig/set",
      params: {
        config: {
          url: "https://your-server.com/webhook/a2a",
          headers: {
            "Authorization": "Bearer webhook-token"
          },
          events: ["task.completed", "task.failed"],
          secret: "your-webhook-secret"
        }
      }
    })
  });

  const result = await response.json();
  console.log(result);
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "jsonrpc": "2.0",
    "result": {
      "configured": true,
      "configId": "webhook-config-123",
      "url": "https://your-server.com/webhook/a2a",
      "events": ["task.completed", "task.failed"]
    },
    "id": "req-webhook-config"
  }
  ```
</ResponseExample>

***

## tasks/pushNotificationConfig/get

Retrieve current webhook configuration for the agent.

### Request Parameters

<ParamField body="jsonrpc" type="string" required>
  JSON-RPC version, must be `"2.0"`
</ParamField>

<ParamField body="id" type="string" required>
  Unique identifier for this request
</ParamField>

<ParamField body="method" type="string" required>
  Must be `"tasks/pushNotificationConfig/get"`
</ParamField>

<ParamField body="params" type="object">
  Optional parameters

  <Expandable title="params properties">
    <ParamField body="params.taskId" type="string">
      Get configuration for specific task (if task-specific config exists)
    </ParamField>
  </Expandable>
</ParamField>

### Response

<ResponseField name="jsonrpc" type="string">
  JSON-RPC version, always `"2.0"`
</ResponseField>

<ResponseField name="result" type="object">
  Current webhook configuration

  <Expandable title="result properties">
    <ResponseField name="result.config" type="object">
      Webhook configuration (null if not configured)

      <Expandable title="config properties">
        <ResponseField name="result.config.url" type="string">
          Configured webhook URL
        </ResponseField>

        <ResponseField name="result.config.events" type="array">
          Subscribed events
        </ResponseField>

        <ResponseField name="result.config.retryPolicy" type="object">
          Retry configuration
        </ResponseField>

        <ResponseField name="result.config.createdAt" type="string">
          Configuration creation timestamp
        </ResponseField>

        <ResponseField name="result.config.lastUsed" type="string">
          Last webhook delivery timestamp
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="result.configId" type="string">
      Configuration identifier
    </ResponseField>

    <ResponseField name="result.active" type="boolean">
      Whether webhook is currently active
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "http://localhost:8000/api/v1/a2a/my-agent" \
    -H "Content-Type: application/json" \
    -H "x-api-key: your-api-key" \
    -d '{
      "jsonrpc": "2.0",
      "id": "req-get-webhook",
      "method": "tasks/pushNotificationConfig/get",
      "params": {}
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json Configured theme={null}
  {
    "jsonrpc": "2.0",
    "result": {
      "config": {
        "url": "https://your-server.com/webhook/a2a",
        "events": ["task.completed", "task.failed"],
        "retryPolicy": {
          "maxRetries": 5,
          "backoffMultiplier": 2.0,
          "initialDelay": 2
        },
        "createdAt": "2024-01-15T10:30:00Z",
        "lastUsed": "2024-01-15T11:45:30Z"
      },
      "configId": "webhook-config-123",
      "active": true
    },
    "id": "req-get-webhook"
  }
  ```

  ```json Not Configured theme={null}
  {
    "jsonrpc": "2.0",
    "result": {
      "config": null,
      "configId": null,
      "active": false
    },
    "id": "req-get-webhook"
  }
  ```
</ResponseExample>

***

## agent/authenticatedExtendedCard

Get detailed information about the agent, including capabilities, supported features, and metadata.

### Request Parameters

<ParamField body="jsonrpc" type="string" required>
  JSON-RPC version, must be `"2.0"`
</ParamField>

<ParamField body="id" type="string" required>
  Unique identifier for this request
</ParamField>

<ParamField body="method" type="string" required>
  Must be `"agent/authenticatedExtendedCard"`
</ParamField>

<ParamField body="params" type="object">
  Optional parameters

  <Expandable title="params properties">
    <ParamField body="params.includeCapabilities" type="boolean">
      Include detailed capability information (default: true)
    </ParamField>

    <ParamField body="params.includeMetrics" type="boolean">
      Include usage metrics and statistics (default: false)
    </ParamField>
  </Expandable>
</ParamField>

### Response

<ResponseField name="jsonrpc" type="string">
  JSON-RPC version, always `"2.0"`
</ResponseField>

<ResponseField name="result" type="object">
  Agent information

  <Expandable title="result properties">
    <ResponseField name="result.agent" type="object">
      Agent details

      <Expandable title="agent properties">
        <ResponseField name="result.agent.id" type="string">
          Agent unique identifier
        </ResponseField>

        <ResponseField name="result.agent.name" type="string">
          Agent display name
        </ResponseField>

        <ResponseField name="result.agent.description" type="string">
          Agent description
        </ResponseField>

        <ResponseField name="result.agent.version" type="string">
          Agent version
        </ResponseField>

        <ResponseField name="result.agent.type" type="string">
          Agent type (e.g., "llm", "workflow", "sequential")
        </ResponseField>

        <ResponseField name="result.agent.status" type="string">
          Current agent status ("active", "inactive", "maintenance")
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="result.capabilities" type="object">
      Agent capabilities

      <Expandable title="capabilities properties">
        <ResponseField name="result.capabilities.supportedMethods" type="array">
          List of supported A2A methods
        </ResponseField>

        <ResponseField name="result.capabilities.fileUpload" type="object">
          File upload capabilities

          <Expandable title="fileUpload properties">
            <ResponseField name="result.capabilities.fileUpload.supported" type="boolean">
              Whether file upload is supported
            </ResponseField>

            <ResponseField name="result.capabilities.fileUpload.maxFileSize" type="number">
              Maximum file size in bytes
            </ResponseField>

            <ResponseField name="result.capabilities.fileUpload.supportedTypes" type="array">
              Supported MIME types
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="result.capabilities.streaming" type="boolean">
          Whether streaming is supported
        </ResponseField>

        <ResponseField name="result.capabilities.multiTurn" type="boolean">
          Whether multi-turn conversations are supported
        </ResponseField>

        <ResponseField name="result.capabilities.webhooks" type="boolean">
          Whether webhook notifications are supported
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="result.limits" type="object">
      Usage limits and quotas

      <Expandable title="limits properties">
        <ResponseField name="result.limits.requestsPerMinute" type="number">
          Rate limit for requests per minute
        </ResponseField>

        <ResponseField name="result.limits.concurrentTasks" type="number">
          Maximum concurrent tasks
        </ResponseField>

        <ResponseField name="result.limits.maxMessageLength" type="number">
          Maximum message length in characters
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="result.metrics" type="object">
      Usage metrics (if requested)

      <Expandable title="metrics properties">
        <ResponseField name="result.metrics.totalRequests" type="number">
          Total requests processed
        </ResponseField>

        <ResponseField name="result.metrics.averageResponseTime" type="number">
          Average response time in milliseconds
        </ResponseField>

        <ResponseField name="result.metrics.successRate" type="number">
          Success rate percentage
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "http://localhost:8000/api/v1/a2a/my-agent" \
    -H "Content-Type: application/json" \
    -H "x-api-key: your-api-key" \
    -d '{
      "jsonrpc": "2.0",
      "id": "req-agent-info",
      "method": "agent/authenticatedExtendedCard",
      "params": {
        "includeCapabilities": true,
        "includeMetrics": true
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://localhost:8000/api/v1/a2a/my-agent', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'your-api-key'
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "req-agent-info",
      method: "agent/authenticatedExtendedCard",
      params: {
        includeCapabilities: true,
        includeMetrics: false
      }
    })
  });

  const result = await response.json();
  console.log(result);
  ```
</RequestExample>

<ResponseExample>
  ```json Agent Information theme={null}
  {
    "jsonrpc": "2.0",
    "result": {
      "agent": {
        "id": "my-agent",
        "name": "Customer Support Assistant",
        "description": "AI agent specialized in customer support and FAQ responses",
        "version": "1.2.0",
        "type": "llm",
        "status": "active"
      },
      "capabilities": {
        "supportedMethods": [
          "message/send",
          "message/stream",
          "tasks/get",
          "tasks/cancel",
          "tasks/pushNotificationConfig/set",
          "tasks/pushNotificationConfig/get",
          "agent/authenticatedExtendedCard"
        ],
        "fileUpload": {
          "supported": true,
          "maxFileSize": 5242880,
          "supportedTypes": [
            "text/plain",
            "application/pdf",
            "image/jpeg",
            "image/png"
          ]
        },
        "streaming": true,
        "multiTurn": true,
        "webhooks": true
      },
      "limits": {
        "requestsPerMinute": 100,
        "concurrentTasks": 10,
        "maxMessageLength": 10000
      },
      "metrics": {
        "totalRequests": 15420,
        "averageResponseTime": 850,
        "successRate": 98.5
      }
    },
    "id": "req-agent-info"
  }
  ```
</ResponseExample>

***

## Webhook Payload Format

When webhooks are configured, your endpoint will receive POST requests with the following payload structure:

### Webhook Request Headers

```http theme={null}
Content-Type: application/json
X-Webhook-Event: task.completed
X-Webhook-Signature: sha256=<hmac-signature>
X-Webhook-Delivery: <delivery-id>
User-Agent: EvoAI-Webhook/1.0
```

### Webhook Payload

```json theme={null}
{
  "event": "task.completed",
  "timestamp": "2024-01-15T10:32:15Z",
  "agentId": "my-agent",
  "taskId": "task-123",
  "data": {
    "status": {
      "state": "completed",
      "message": {
        "role": "agent",
        "parts": [
          {
            "type": "text",
            "text": "Task completed successfully"
          }
        ]
      }
    },
    "contextId": "ctx-abc123",
    "duration": 125000,
    "completedAt": "2024-01-15T10:32:15Z"
  },
  "delivery": {
    "attempt": 1,
    "maxAttempts": 5
  }
}
```

### Webhook Events

<AccordionGroup>
  <Accordion icon="clock" title="task.submitted">
    Sent when a task is submitted and queued for processing.

    **Data includes:** `taskId`, `submittedAt`, `estimatedDuration`
  </Accordion>

  <Accordion icon="gear" title="task.working">
    Sent when a task starts processing (optional, based on agent implementation).

    **Data includes:** `taskId`, `startedAt`, `progress`
  </Accordion>

  <Accordion icon="check" title="task.completed">
    Sent when a task completes successfully.

    **Data includes:** `taskId`, `status.message`, `contextId`, `duration`, `completedAt`
  </Accordion>

  <Accordion icon="x" title="task.failed">
    Sent when a task fails during processing.

    **Data includes:** `taskId`, `status.error`, `duration`, `failedAt`
  </Accordion>

  <Accordion icon="ban" title="task.canceled">
    Sent when a task is canceled.

    **Data includes:** `taskId`, `reason`, `canceledAt`
  </Accordion>
</AccordionGroup>

## Webhook Security

### Signature Verification

If you provide a `secret` in your webhook configuration, each webhook request will include an HMAC-SHA256 signature:

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  return `sha256=${expectedSignature}` === signature;
}

// Usage
const isValid = verifyWebhookSignature(
  JSON.stringify(webhookPayload),
  request.headers['x-webhook-signature'],
  'your-webhook-secret'
);
```

### Best Practices

<AccordionGroup>
  <Accordion icon="shield" title="Security">
    * **Always verify signatures** when using webhook secrets
    * **Use HTTPS endpoints** for webhook URLs
    * **Validate payload structure** before processing
    * **Implement idempotency** using delivery IDs
  </Accordion>

  <Accordion icon="lightning" title="Performance">
    * **Respond quickly** (\< 5 seconds) to avoid retries
    * **Process asynchronously** for complex operations
    * **Return 2xx status codes** for successful processing
  </Accordion>

  <Accordion icon="gear" title="Reliability">
    * **Handle duplicate deliveries** gracefully
    * **Implement proper error handling** for webhook processing
    * **Monitor webhook delivery success** rates
  </Accordion>
</AccordionGroup>
