# Mandar un evento de prueba

`POST https://api.fiscalisto.com/v1/webhook_endpoints/{id}/test`

Manda ahora, una sola vez y sin reintentos, un evento del tipo que elija con un objeto de ejemplo (sus id no existen), firmado como los reales, aunque el webhook no escuche ese tipo. La respuesta trae lo que contestó su servidor. El evento no sale en GET /v1/events, pero sí en las entregas del webhook.

## Parámetros

| Nombre | Dónde | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `id` | ruta | sí | El id del objeto. |
| `Idempotency-Key` | encabezado |  | Opcional (los SDK la mandan solos). Si la respuesta se pierde, repita la solicitud con el mismo valor durante 24 horas: contesta lo mismo, con idempotent-replayed: true, y no lo hace dos veces (ni crea, ni manda correos, ni cobra). |

## Cuerpo

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `type` | `invoice.stamped`, `invoice.failed`, `invoice.canceled`, `invoice.cancellation_pending`, `invoice.cancellation_rejected`, `invoice.paid`, `invoice.partially_paid`, `retention.stamped`, `retention.failed`, `retention.canceled`, `invoice_batch.completed`, `customer_data_request.completed`, `sat_download.completed`, `sat_download.failed`, `sat_declaration.created`, `sat_declaration.updated`, `ticket.invoiced`, `ticket.included_in_global`, `recurring_invoice.failed`, `quote.viewed`, `quote.accepted`, `quote.changes_requested`, `quote.rejected`, `issuer.ready`, `balance.low`, `test_clock.ready` |  | El evento a mandar. Por omisión invoice.stamped. (por omisión "invoice.stamped") |

Ejemplo:

```json
{
  "type": "invoice.failed"
}
```

## Con el SDK de TypeScript

```ts
import { Fiscalisto } from "fiscalisto";

// La llave viene de FISCALISTO_API_KEY.
const fiscalisto = new Fiscalisto();

const webhookTest = await fiscalisto.webhookEndpoints.test("id", { type: "invoice.failed" }, { idempotencyKey: "pedido-A-1042" });
```

## Con el SDK de Python

```python
from fiscalisto import Fiscalisto

# La llave viene de FISCALISTO_API_KEY.
fiscalisto = Fiscalisto()

webhook_test = fiscalisto.webhook_endpoints.test("id", {"type": "invoice.failed"}, idempotency_key="pedido-A-1042")
```

## Con el SDK de PHP

```php
<?php

use Fiscalisto\Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
$fiscalisto = new Fiscalisto();

$webhookTest = $fiscalisto->webhookEndpoints->test('id', ['type' => 'invoice.failed'], ['idempotency_key' => 'pedido-A-1042']);
```

## Con el SDK de .NET

```csharp
using Fiscalisto;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var webhookTest = await fiscalisto.WebhookEndpoints.TestAsync("id", new TestWebhookEndpointParams { Type = "invoice.failed" }, new RequestOptions { IdempotencyKey = "pedido-A-1042" });
```

## Con el SDK de Go

```go
package main

import (
	"context"
	"fmt"
	"log"

	fiscalisto "fiscalisto.com/go"
)

func main() {
	// La llave viene de FISCALISTO_API_KEY.
	client, err := fiscalisto.NewClient("")
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	webhookTest, err := client.WebhookEndpoints.Test(ctx, "id", &fiscalisto.TestWebhookEndpointParams{
		Type: fiscalisto.String("invoice.failed"),
	}, fiscalisto.WithIdempotencyKey("pedido-A-1042"))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%+v\n", *webhookTest)
}
```

## Con el SDK de Java

```java
import com.fiscalisto.FiscalistoClient;
import com.fiscalisto.RequestOptions;
import com.fiscalisto.model.TestWebhookEndpointParams;

// La llave viene de FISCALISTO_API_KEY.
var fiscalisto = new FiscalistoClient();

var webhookTest = fiscalisto.webhookEndpoints().test("id", new TestWebhookEndpointParams().setType("invoice.failed"), RequestOptions.idempotencyKey("pedido-A-1042"));
System.out.println(webhookTest);
```

## Respuesta 200

Correcto.

Un objeto `WebhookTest`:

| Campo | Tipo | Siempre viene | Descripción |
| --- | --- | --- | --- |
| `object` | `"webhook_test"` | sí | Qué tipo de objeto es («invoice», «customer»…). |
| `event` | objeto | sí | Algo que pasó en su cuenta: el objeto completo como quedó. Se manda a sus webhooks firmado (Standard Webhooks). |
| `event.id` | string | sí | Identificador del objeto, con su prefijo (iss_, inv_, ret_, cus_, prd_, emp_, bat_, brn_, whs_, stm_, adj_, evt_, whe_). |
| `event.object` | `"event"` | sí | Qué tipo de objeto es («invoice», «customer»…). |
| `event.type` | string | sí | Qué pasó: invoice.stamped, invoice.failed, invoice.canceled, invoice.cancellation_pending, invoice.cancellation_rejected, invoice.paid, invoice.partially_paid, retention.stamped, retention.failed, retention.canceled, invoice_batch.completed, customer_data_request.completed, sat_download.completed, sat_download.failed, sat_declaration.created, sat_declaration.updated, ticket.invoiced, ticket.included_in_global, recurring_invoice.failed, quote.viewed, quote.accepted, quote.changes_requested, quote.rejected, issuer.ready, balance.low o test_clock.ready. |
| `event.api_version` | string | sí | Versión de la API con que se armó el objeto. |
| `event.livemode` | boolean | sí | true en producción (llaves fk_live_), false en pruebas (fk_test_). Lo de pruebas no vale ante el SAT. |
| `event.created_at` | string (date-time) | sí | Cuándo se creó, ISO 8601 con la hora de la Ciudad de México (-06:00). |
| `event.data` | objeto | sí | Lo que cambió, en data.object: el comprobante (o el lote) completo, como lo contesta su GET. |
| `event.data.object` | objeto | sí | El objeto como quedó: una factura, una constancia o un lote. |
| `delivery` | objeto | sí | Cómo le fue: ok si contestó 2xx, el código, el error y el inicio de su respuesta. |
| `delivery.ok` | boolean | sí | true si su servidor contestó 2xx. |
| `delivery.status` | integer o null | sí | El código HTTP que contestó; null si no se pudo conectar. |
| `delivery.error` | string o null | sí | Qué falló (sin respuesta, no se pudo conectar, otro código), o null. |
| `delivery.response_body` | string o null | sí | El inicio de lo que contestó su servidor (hasta 2,000 caracteres). |
| `delivery.duration_ms` | integer | sí | Cuánto tardó su servidor, en milisegundos. (de -9007199254740991 a 9007199254740991) |

```json
{
  "object": "webhook_test",
  "event": {
    "id": "evt_0PKhIdhYuAGwzmMQYfkc",
    "object": "event",
    "type": "invoice.stamped",
    "api_version": "2026-10-24",
    "livemode": false,
    "created_at": "2026-10-24T10:15:42-06:00",
    "data": {
      "object": {
        "id": "inv_OufpKqnrvx9p28SINJVjjWKYRhojBTJb8P",
        "object": "invoice",
        "livemode": false,
        "issuer": "iss_OufpKqnrvx9p",
        "branch": null,
        "type": "I",
        "status": "valid",
        "uuid": "5F1E8C2A-3B7D-4C9E-A1B2-C3D4E5F60718",
        "series": null,
        "folio": "1",
        "date": "2026-10-24T10:15:42",
        "customer": {
          "tax_id": "ICV060329BY0",
          "legal_name": "INMOBILIARIA CVA",
          "tax_system": "601",
          "zip": "33826"
        },
        "use": "G03",
        "payment_form": "03",
        "payment_method": "PUE",
        "currency": "MXN",
        "exchange_rate": null,
        "items": [
          {
            "description": "Consultoría",
            "product_key": "80101500",
            "unit_key": "E48",
            "unit_name": "Unidad de servicio",
            "quantity": 1,
            "unit_price": 1000,
            "taxability": "02",
            "iva": "0.16"
          }
        ],
        "subtotal": 1000,
        "discount": 0,
        "taxes": {
          "iva": 160,
          "ieps": 0,
          "iva_withheld": 0,
          "isr_withheld": 0,
          "local_transferred": 0,
          "local_withheld": 0
        },
        "total": 1160,
        "payment_status": "paid",
        "amount_due": 0,
        "amount_paid": 1160,
        "related": null,
        "cancellation": null,
        "email": null,
        "error": null,
        "recurring_invoice": null,
        "created_at": "2026-10-24T10:15:42-06:00",
        "metadata": {}
      }
    }
  },
  "delivery": {
    "ok": true,
    "status": 200,
    "error": null,
    "response_body": "{\"received\":true}",
    "duration_ms": 182
  }
}
```

## Errores

Puede responder 400, 401, 403, 404, 429, 500 con el cuerpo de error de siempre; cada código está en https://fiscalisto.com/docs/api/errores.md.
