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

# Webhooks

> Recibe un POST firmado en el momento en que algo ocurre en StockShift, en lugar de consultarlo periódicamente.

Un endpoint de webhook es una dirección a la que StockShift envía eventos. Agrega uno en la app, en **Configuración > Webhooks**, o con las [operaciones de endpoints de webhook](https://docs.stockshift.io/es/api-reference/introduction.md) de la API.

## Agrega un endpoint

1. Presiona **Nuevo endpoint**.
2. Ingresa la URL. Debe ser HTTPS y accesible desde internet. Las direcciones privadas y locales se rechazan.
3. Marca los eventos que quieres. La [lista de eventos](https://docs.stockshift.io/es/api-reference/webhook-events.md) tiene el cuerpo de cada uno.
4. Presiona **Agregar endpoint**.
5. Copia el secreto de firma que aparece. Se muestra una sola vez. **Rotar secreto** genera uno nuevo.

**Enviar ping de prueba** envía un evento `webhook.ping` de inmediato para que puedas revisar tu endpoint.

## Qué recibe tu endpoint

Cada evento es un `POST` con un cuerpo JSON:

```json theme={null}
{
  "id": "0199f2d4-6b1e-7c3a-9a51-2f0e8c1d4b7a",
  "type": "inventory.stock.adjusted",
  "created": "2026-10-29T14:03:11Z",
  "data": {}
}
```

Responde con cualquier `2xx` en menos de 10 segundos. StockShift no sigue redirecciones.

Un evento puede llegar más de una vez y fuera de orden. Los reintentos conservan el mismo `id`, así que guárdalo y omite los eventos que ya procesaste.

## Revisa la firma

Revisa el encabezado `StockShift-Signature` antes de confiar en el cuerpo. Tiene el formato `t=1760000000,v1=5257a8...`:

* `t` es la hora Unix en que se envió el evento.
* `v1` es el HMAC-SHA256 de `<t>.<raw body>` con el secreto de firma del endpoint, en hexadecimal.

Calcula el mismo HMAC sobre el cuerpo sin procesar, exactamente como llegó, compáralo en tiempo constante y rechaza todo lo que tenga un `t` de más de cinco minutos de antigüedad. Cada SDK tiene una función auxiliar que hace todo esto:

```ts TypeScript theme={null}
import { verifyWebhook, WebhookVerificationError } from "@stockshift/sdk";

export async function POST(request: Request): Promise<Response> {
  try {
    const event = await verifyWebhook({
      payload: await request.text(),
      header: request.headers.get("StockShift-Signature"),
      secret: process.env.STOCKSHIFT_WEBHOOK_SECRET!,
    });
    if (event.type === "inventory.stock.adjusted") {
      console.log(event.data.item_id, event.data.quantity);
    }
    return new Response(null, { status: 204 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) {
      return new Response(null, { status: 400 });
    }
    throw error;
  }
}
```

```php PHP theme={null}
use StockShift\Sdk\Exception\WebhookVerificationException;
use StockShift\Sdk\Webhook;

try {
    $event = Webhook::verify(
        file_get_contents('php://input'),
        $_SERVER['HTTP_STOCKSHIFT_SIGNATURE'] ?? null,
        getenv('STOCKSHIFT_WEBHOOK_SECRET'),
    );
} catch (WebhookVerificationException) {
    http_response_code(400);
    exit;
}

http_response_code(204);
```

```python Python theme={null}
from stockshift import WebhookVerificationError, verify_webhook
from stockshift.models import InventoryStockAdjustedEvent


def receive(body: bytes, signature: str | None) -> int:
    try:
        event = verify_webhook(body, signature, os.environ["STOCKSHIFT_WEBHOOK_SECRET"])
    except WebhookVerificationError:
        return 400

    if isinstance(event, InventoryStockAdjustedEvent):
        print(event.data.item_id, event.data.quantity)
    return 204
```

```go Go theme={null}
verifier := stockshift.WebhookVerifier{Secret: os.Getenv("STOCKSHIFT_WEBHOOK_SECRET")}

http.HandleFunc("POST /webhooks/stockshift", func(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	event, err := verifier.Verify(body, r.Header.Get(stockshift.SignatureHeader))
	if err != nil {
		http.Error(w, "", http.StatusBadRequest)
		return
	}
	fmt.Println(event.ID, event.Type)
	w.WriteHeader(http.StatusNoContent)
})
```

```rust Rust theme={null}
use stockshift::webhook::{EventData, Webhook};

fn receive(body: &[u8], signature: Option<&str>, secret: &str) -> u16 {
    let Ok(event) = Webhook::new(secret).verify(body, signature) else {
        return 400;
    };
    if let EventData::InventoryStockAdjusted(adjusted) = &event.data {
        println!("{} {}", adjusted.item_id, adjusted.quantity);
    }
    204
}
```

```csharp .NET theme={null}
app.MapPost("/webhooks/stockshift", async (HttpRequest request) =>
{
    using var reader = new StreamReader(request.Body);
    var payload = await reader.ReadToEndAsync();

    try
    {
        var webhookEvent = StockShiftWebhook.Verify(payload, request.Headers[StockShiftWebhook.SignatureHeader], secret);
        return Results.NoContent();
    }
    catch (WebhookVerificationException)
    {
        return Results.BadRequest();
    }
});
```

En una app de Laravel, el [paquete de Laravel](https://docs.stockshift.io/es/sdks/laravel.md) agrega una ruta que revisa la firma y dispara un evento de Laravel por cada entrega.

## Reintentos

Una entrega que recibe cualquier respuesta distinta de `2xx` se vuelve a intentar después de 1, 5, 30, 120, 360 y 720 minutos. Si sigue fallando, o si pasan 24 horas, la entrega se marca como fallida, el endpoint se desactiva y los propietarios de la organización reciben un correo electrónico. Los eventos que ocurren mientras un endpoint está desactivado no se envían después.

La tarjeta **Entregas** de un endpoint muestra sus 50 entregas más recientes con su estado, código de respuesta, duración e intentos. **Reintentar** vuelve a enviar una entrega fallida una vez más. Las entregas se conservan durante 30 días.

Para pausar un endpoint, desmarca **Activado** y presiona **Guardar endpoint**.


## Related topics

- [Eventos de webhook](https://docs.stockshift.io/es/api-reference/webhook-events.md)
- [Lista los endpoints de webhook](https://docs.stockshift.io/es/api-reference/webhooks/lista-los-endpoints-de-webhook.md)
- [Elimina un endpoint de webhook](https://docs.stockshift.io/es/api-reference/webhooks/elimina-un-endpoint-de-webhook.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.