Webhooks

Quando você cria um agente com uma URL de webhook, o Cursor envia solicitações HTTP POST para te notificar sobre mudanças de status. No momento, apenas eventos statusChange são suportados, especificamente quando um agente entra nos estados ERROR ou FINISHED.

Verificação de webhook

Para garantir que as solicitações de webhook são de fato do Cursor, verifica a assinatura incluída em cada solicitação:

Headers

Cada solicitação de webhook inclui os seguintes headers:
  • X-Webhook-Signature – Contém a assinatura HMAC-SHA256 no formato sha256=<hex_digest>
  • X-Webhook-ID – Um identificador exclusivo para esta entrega (útil para logging)
  • X-Webhook-Event – O tipo de evento (no momento, apenas statusChange)
  • User-Agent – Sempre definido como Cursor-Agent-Webhook/1.0

Verificação de assinatura

Para verificar a assinatura do webhook, calcula a assinatura esperada e compara com a assinatura recebida:
const crypto = require('crypto');

function verifyWebhook(secret, rawBody, signature) {
  const expectedSignature = 'sha256=' + 
    crypto.createHmac('sha256', secret)
          .update(rawBody)
          .digest('hex');
  
  return signature === expectedSignature;
}
import hmac
import hashlib

def verify_webhook(secret, raw_body, signature):
    expected_signature = 'sha256=' + hmac.new(
        secret.encode(),
        raw_body,
        hashlib.sha256
    ).hexdigest()
    
    return signature == expected_signature
Sempre usa o corpo bruto da solicitação (antes de qualquer parsing) ao calcular a assinatura.

Formato do payload

O payload do webhook é enviado como JSON com a seguinte estrutura:
{
  "event": "statusChange",
  "timestamp": "2024-01-15T10:30:00Z",
  "id": "bc_abc123",
  "status": "FINISHED",
  "source": {
    "repository": "https://github.com/your-org/your-repo",
    "ref": "main"
  },
  "target": {
    "url": "https://cursor.com/agents?id=bc_abc123",
    "branchName": "cursor/add-readme-1234",
    "prUrl": "https://github.com/your-org/your-repo/pull/1234"
  },
  "summary": "Added README.md with installation instructions"
}
Observa que alguns campos são opcionais e só serão incluídos quando disponíveis.

Boas práticas

  • Verifica assinaturas – Sempre verifica a assinatura do webhook pra garantir que a requisição é do Cursor
  • Lida com novas tentativas – Webhooks podem ser reenviados se teu endpoint retornar um código de status de erro
  • Responde rápido – Retorna um código de status 2xx o quanto antes
  • Usa HTTPS – Sempre usa URLs HTTPS pros endpoints de webhook em produção
  • Armazena os payloads brutos – Armazena o payload bruto do webhook pra depuração e verificação futura