Tipos de dispersión
Cómo programar dispersiones puntuales, con fecha específica o recurrentes a un beneficiario
Una instrucción de dispersión (el objeto payout_rule en la API) le dice a Conekta cuánto pagarle a un beneficiario y con qué periodicidad. El beneficiario debe estar validated_active para poder asociarle una.
Tipos de dispersión
rule_type | Comportamiento |
|---|---|
one_time | Instrucción manual. Se ejecuta on-demand en el momento de crearla si hay saldo disponible, o si no en el próximo proceso nocturno — ver Ejecución on-demand. Puedes cancelarla mientras siga sin ejecutarse. |
scheduled | Se ejecuta una única vez, en la fecha que indiques (scheduled_date). |
recurrent | Se repite automáticamente según frequency: daily, weekly o monthly. |
Todas las instrucciones de dispersión comparten los mismos campos base (payee_id, amount, priority, name, concept, external_reference) y agregan campos propios según el tipo.
Crear una instrucción de dispersión
curl --request POST \
--url https://api.conekta.io/payout_rules \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB' \
--header 'Content-Type: application/json' \
--data '{
"rule_type": "one_time",
"payee_id": "payee_xxx",
"amount": 10000,
"priority": 1,
"name": "Liquidación proveedor",
"concept": "Pago factura mayo"
}'Parámetros comunes:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
rule_type | String | Sí | one_time, scheduled o recurrent. |
payee_id | String | Sí | ID de un beneficiario validated_active. |
amount | Integer | Sí | Monto en centavos MXN (ej. 10000 = $100.00), mayor a 0. Debe ser un entero — un valor con decimales o enviado como string responde 422 invalid_amount_format. Misma unidad que los montos en Seguimiento de dispersiones. |
priority | Integer | No | Default 0. Determina el orden en que la instrucción aparece al listarla. No determina el orden de ejecución nocturno — ver Cómo se prioriza la ejecución más abajo. |
name | String | No | Nombre descriptivo, ej. "Nómina quincena 1". |
concept | String | No | Concepto SPEI visible para el beneficiario. Default: "Pago automático Conekta". |
external_reference | String | No | Referencia numérica propia (máx. 7 dígitos, /\A\d{1,7}\z/) que se usa tal cual como referencia SPEI en cada dispersión que resulte de esta instrucción, en vez del valor interno que Conekta deriva por defecto. Útil si necesitas reconciliar contra tus propios sistemas. Si se omite, o si no es numérico de ≤7 dígitos, se sigue generando el valor interno como siempre — un valor inválido devuelve 422. |
Parámetros según rule_type:
| Parámetro | Aplica a | Descripción |
|---|---|---|
scheduled_date | scheduled | Fecha YYYY-MM-DD, hoy o futura. Una fecha de hoy no queda huérfana esperando al proceso nocturno — se dispara on-demand al crear/editar la regla, ver Ejecución on-demand. |
frequency | recurrent | daily, weekly o monthly. |
recurrence_day | recurrent | Días de ejecución. weekly: uno o más valores 0–6 (0 = domingo). monthly: uno o más días del mes, ej. [15] o [1,15] para quincenas. |
last_day_of_month | recurrent + monthly | Si es true y no envías recurrence_day, se ejecuta solo el último día del mes. Si lo combinas con recurrence_day: [N] (un solo valor), se ejecuta el día N y además el último día de cada mes — útil para quincenas reales, cubriendo automáticamente meses de 28 a 31 días. No es compatible con 2 o más valores en recurrence_day — la combinación se rechaza con 422. |
start_date | recurrent | Fecha opcional de inicio de la ventana de ejecución. |
end_date | recurrent | Obligatorio. Fecha de fin de la ventana de ejecución/vigencia de la instrucción, máximo 12 meses desde hoy. Ver Vigencia y renovación de instrucciones recurrentes. |
auto_renew | recurrent | Boolean, default false. Determina qué pasa cuando llega end_date sin renovarla — ver Vigencia y renovación de instrucciones recurrentes. |
Ejemplos
Pago puntual (próximo proceso nocturno):
{ "rule_type": "one_time", "payee_id": "payee_xxx", "amount": 10000, "name": "Liquidación proveedor" }Pago en una fecha específica:
{ "rule_type": "scheduled", "payee_id": "payee_xxx", "amount": 50000, "scheduled_date": "2026-06-15", "name": "Bono anual" }Nómina mensual, día 15:
{ "rule_type": "recurrent", "payee_id": "payee_xxx", "amount": 150000, "frequency": "monthly", "recurrence_day": [15], "start_date": "2026-06-01", "name": "Nómina mensual" }Renta el último día de cada mes:
{ "rule_type": "recurrent", "payee_id": "payee_xxx", "amount": 150000, "frequency": "monthly", "last_day_of_month": true, "name": "Renta fin de mes" }Nómina quincenal real (día 15 y último día del mes):
{ "rule_type": "recurrent", "payee_id": "payee_xxx", "amount": 200000, "frequency": "monthly", "recurrence_day": [15], "last_day_of_month": true, "name": "Nómina quincenal" }Pago semanal (lunes, miércoles y viernes):
{ "rule_type": "recurrent", "payee_id": "payee_xxx", "amount": 80000, "frequency": "weekly", "recurrence_day": [1,3,5], "name": "Servicios L/M/V" }Pago puntual con referencia propia para reconciliación:
{ "rule_type": "one_time", "payee_id": "payee_xxx", "amount": 10000, "name": "Liquidación proveedor", "external_reference": "1234567" }
external_referenceen instruccionesrecurrentCada ejecución de una instrucción
recurrentgenera una dispersión distinta, pero si definesexternal_referenceen la instrucción, todas sus ejecuciones lo reenvían igual (a diferencia del valor interno por default, que es único por dispersión). Valida el comportamiento en modo de pruebas antes de habilitarexternal_referenceen una instrucciónrecurrenten producción.
Respuesta 201 Created:
{
"id": "6a188111ff51790001e279fb",
"object": "payout_rule",
"rule_type": "one_time",
"payee_id": "payee_317roDjGQMta9DYVo",
"amount": 10000,
"priority": 1,
"status": "scheduled",
"name": "Liquidación proveedor",
"concept": "Pago factura mayo",
"auto_renew": null,
"last_renewed_at": null,
"paused_by_expiration_at": null,
"created_at": 1779990801,
"updated_at": 1779990801
}El
statusinicial es"scheduled"para instruccionesone_timeyscheduled, y"active"para instruccionesrecurrent.
last_day_of_month,auto_renew,last_renewed_atypaused_by_expiration_atsolo traen valor en instruccionesrecurrent— sonnullparaone_timeyscheduled.
Errores:
| Código | Motivo |
|---|---|
422 Unprocessable Entity | El payee_id no corresponde a un beneficiario validated_active, falta un campo requerido para el rule_type elegido, amount no es un entero mayor a 0 (invalid_amount_format si no es entero), recurrence_day trae 2+ valores junto con last_day_of_month: true, external_reference no es numérico de máximo 7 dígitos, end_date falta en una regla recurrent (end_date_required) o excede los 12 meses (end_date_exceeds_max_commitment), o amount excede el max_amount_limit configurado en el beneficiario (amount_exceeds_payee_limit). |
El límite del beneficiario solo se valida al crear
amount_exceeds_payee_limitse rechaza en elPOSTinicial, pero no se vuelve a validar en unPATCHque suba elamount— ni si editas elmax_amount_limitdel beneficiario después de crear la instrucción. En ambos casos la instrucción se sigue creando/actualizando sin error, y el límite se aplica recién en la ejecución nocturna, donde la instrucción quedaskippeden vez de dispersarse. Ver Límite máximo por beneficiario.
Ejecución on-demand
Si al crear (POST) o editar (PATCH) una instrucción esta ya aplica para hoy — una one_time (siempre aplica de inmediato), una scheduled con scheduled_date de hoy, o una recurrent cuyo recurrence_day/frequency matchea hoy — Conekta intenta dispersarla en el mismo momento, sin esperar al proceso nocturno:
- Si ya hay saldo suficiente en tu cuenta de dispersiones, la dispersión sale en el mismo minuto en que creas o editas la regla.
- Si no hay saldo, la transacción queda
pendingigual que si hubieras esperado al proceso nocturno — se recoge en la corrida de esa noche, o antes si llega un fondeo adicional (MONEY_IN).
El on-demand nunca hace fallar tu requestEl intento de dispersión inmediata es best-effort: si el intento falla, tu
POST/PATCHigual responde201/200— la regla queda creada/actualizada con normalidad y la dispersión simplemente espera al próximo proceso nocturno. La API nunca refleja un fallo de este intento como error.
Sigue el resultado por los webhooks payout.* o consultando Seguimiento de dispersiones, igual que con cualquier otra dispersión.
Listar instrucciones de dispersión
# Todas las instrucciones del negocio
curl --request GET \
--url https://api.conekta.io/payout_rules \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'
# Solo las instrucciones de un beneficiario
curl --request GET \
--url 'https://api.conekta.io/payout_rules?payee_id=PAYEE_ID' \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'El resultado viene ordenado por priority descendente y luego por antigüedad. Este es el orden de listado — no necesariamente el orden en que se ejecutan las instrucciones cada noche (ver más abajo).
Obtener una instrucción de dispersión
curl --request GET \
--url https://api.conekta.io/payout_rules/RULE_ID \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'Actualizar una instrucción de dispersión
Puedes actualizar amount, priority, payee_id, name, concept, external_reference y los campos propios del tipo (scheduled_date, frequency, recurrence_day, last_day_of_month, start_date, end_date, auto_renew). El rule_type no se puede cambiar una vez creada la instrucción. end_date sigue el mismo tope de 12 meses al editar (422 end_date_exceeds_max_commitment) y no se puede vaciar — sigue siendo obligatorio en una regla recurrent.
curl --request PATCH \
--url https://api.conekta.io/payout_rules/RULE_ID \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB' \
--header 'Content-Type: application/json' \
--data '{ "amount": 20000, "priority": 3 }'Eliminar una instrucción de dispersión
curl --request DELETE \
--url https://api.conekta.io/payout_rules/RULE_ID \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'Respuesta 200 OK:
{ "id": "6a188111ff51790001e279fb", "object": "payout_rule", "rule_type": "one_time", "deleted": true }
Restricción para instruccionesone_timeUna instrucción
one_timesolo puede eliminarse mientras sigue en estadoscheduled(aún no se ejecutó). Si ya se ejecutó (completed) o falló (failed), el endpoint devuelve422. Las instruccionesscheduledyrecurrentno tienen esta restricción.
Cómo se prioriza la ejecución
Lo siguiente describe el proceso nocturno — el mecanismo que recoge cualquier instrucción que no se haya dispersado ya on-demand (ver Ejecución on-demand arriba).
priorityno determina este ordenEl campo
prioritysolo afecta el orden en que listas tus instrucciones de dispersión — no el orden en que se ejecutan cada noche. Si necesitas garantizar que un pago salga antes que otro cuando el saldo no alcanza para todos, usa el criterio real descrito abajo (tipo de dispersión y monto), nopriority.
Cada noche, Conekta evalúa las instrucciones que aplican para ese día en este orden:
- Instrucciones
scheduled, luegorecurrent, luegoone_time— en ese orden de tipo, no mezcladas entre sí. - Dentro de cada tipo, de menor a mayor monto (
amountascendente) — no porpriority.
Si el saldo disponible no alcanza para todas, las instrucciones se van aplicando en ese orden hasta agotar el saldo; las que no entran quedan SKIPPED por saldo insuficiente. Mientras siga siendo el mismo día, cualquier fondeo adicional vuelve a disparar la evaluación de esas instrucciones pendientes — no es necesario volver a crearlas. Si el día termina sin fondos suficientes, la instrucción no se arrastra sola al día siguiente salvo que tenga activo auto_retry_on_insufficient_funds (opt-in, false por default, tope de 5 días hábiles); sin ese flag, tienes que reintentarla manualmente — ver Reintentar una dispersión fallida por saldo insuficiente.
Orden entre distintos díasLo anterior describe el orden dentro de una misma corrida nocturna. Una instrucción que quedó pendiente por falta de saldo se recoge en la siguiente corrida por antigüedad (la más antigua primero), sin volver a aplicar la jerarquía por tipo frente a las instrucciones nuevas de ese día — por ejemplo, una instrucción
one_timede ayer que quedó pendiente se procesa antes que unascheduledde hoy, simplemente por ser más vieja. Este comportamiento entre días está bajo revisión de producto y puede cambiar; si tu integración depende del orden exacto entre corridas, confirma con tu Ejecutivo de Cuentas antes de construir sobre él.
Límite máximo por beneficiario
Cada beneficiario tiene un max_amount_limit propio — el monto máximo, en centavos MXN, que puede recibir por instrucción (misma unidad y tipo que amount: entero, sin decimales). Esta validación aplica a todas las instrucciones, sin importar cuándo configuraste el límite:
- Al crear la instrucción (
POST /payout_rules): siamountexcede elmax_amount_limitdel beneficiario, la API responde422 amount_exceeds_payee_limitde inmediato — no se crea la instrucción. - En cada ejecución nocturna: si el límite se bajó después de creada la instrucción (por debajo del
amount), esa ejecución individual queda en estadoskipped— nunca se intenta el envío a SPEI, y no cuenta como falla del batch. Ver Detalle de una dispersión.
max_amount_limites obligatorio desde el alta
POST /payouts/payeesrechaza la creación si falta este campo — no hay valor por omisión ni forma de desactivar la validación. Ver Crear un beneficiario.
Al editar el límite de un beneficiario con instrucciones activas apuntándole, la API te avisa si el nuevo valor deja alguna por encima del límite — ver la advertencia no bloqueante en Editar un beneficiario.
Vigencia y renovación de instrucciones recurrentes
Toda instrucción recurrent tiene una fecha de fin (end_date) — no existen instrucciones recurrentes indefinidas. auto_renew determina qué pasa al llegar esa fecha sin que la hayas renovado:
auto_renew | Al llegar end_date sin confirmar | Se puede recuperar |
|---|---|---|
false (default) | La instrucción pasa a expired — terminal, no se puede reactivar. Tienes que crear una instrucción nueva. | No |
true | La instrucción pasa a paused_by_expiration — deja de ejecutarse, pero puedes reactivarla dentro de un periodo de gracia (default 30 días). | Sí, con POST /payout_rules/:id/reactivate |
Antes de llegar a end_date, Conekta emite el evento payout_rule.renewal.upcoming cuando faltan 30, 15 y 3 días (mismo evento para auto_renew: true o false) — ver la sección "Eventos de una regla de dispersión" en Seguimiento de dispersiones. Úsalo para avisar a quien administra tus dispersiones que una regla está por vencer.
Confirmar la renovación de una instrucción activa
Extiende end_date por el mismo periodo que el ciclo vigente, sin cambiar el status (sigue active). Solo aplica a una instrucción recurrent que todavía esté active.
curl --request POST \
--url https://api.conekta.io/payout_rules/RULE_ID/confirm_renewal \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'Respuesta 200 OK: el objeto payout_rule con end_date y last_renewed_at actualizados.
Errores:
| Código | Motivo |
|---|---|
422 Unprocessable Entity | La regla no es recurrent, o no está active (code: not_confirmable). |
Reactivar una instrucción pausada por expiración
Solo aplica a una instrucción en paused_by_expiration, y solo dentro de su periodo de gracia. Recalcula end_date desde hoy, con el mismo periodo del ciclo anterior.
curl --request POST \
--url https://api.conekta.io/payout_rules/RULE_ID/reactivate \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'Respuesta 200 OK: el objeto payout_rule con status: "active" y end_date renovada.
Errores:
| Código | Motivo |
|---|---|
422 Unprocessable Entity | La regla no es recurrent, o no está paused_by_expiration (code: not_reactivatable) — incluye el caso en que ya se archivó (archived) por vencer el periodo de gracia. |
Pasado el periodo de gracia, ya no se puede reactivarUna instrucción
paused_by_expirationque no reactivas a tiempo pasa aarchivedde forma automática — terminal, sin ningún endpoint para revertirla. Si tu integración depende deauto_renew: true, no dejes pasar el periodo de gracia sin llamar areactivateoconfirm_renewal.
Related
- Resumen — Dispersiones a terceros vía SPEI — visión general del flujo completo.
- Gestión de beneficiarios — cómo dar de alta al beneficiario que necesitas antes de crear una instrucción de dispersión.
- Seguimiento de dispersiones — cómo ver si una instrucción ya se ejecutó y con qué resultado.
Updated 4 days ago

