🚀 Lanzamiento v2.3: Activa y desactiva métodos de pago para tu Conekta Checkout desde el Panel, sin tocar tu código. Ver documentación →

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_typeComportamiento
one_timeInstrucció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.
scheduledSe ejecuta una única vez, en la fecha que indiques (scheduled_date).
recurrentSe 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ámetroTipoRequeridoDescripción
rule_typeStringone_time, scheduled o recurrent.
payee_idStringID de un beneficiario validated_active.
amountIntegerMonto 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.
priorityIntegerNoDefault 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.
nameStringNoNombre descriptivo, ej. "Nómina quincena 1".
conceptStringNoConcepto SPEI visible para el beneficiario. Default: "Pago automático Conekta".
external_referenceStringNoReferencia 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ámetroAplica aDescripción
scheduled_datescheduledFecha 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.
frequencyrecurrentdaily, weekly o monthly.
recurrence_dayrecurrentDí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_monthrecurrent + monthlySi 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_daterecurrentFecha opcional de inicio de la ventana de ejecución.
end_daterecurrentObligatorio. 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_renewrecurrentBoolean, 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_reference en instrucciones recurrent

Cada ejecución de una instrucción recurrent genera una dispersión distinta, pero si defines external_reference en 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 habilitar external_reference en una instrucción recurrent en 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 status inicial es "scheduled" para instrucciones one_time y scheduled, y "active" para instrucciones recurrent.

last_day_of_month, auto_renew, last_renewed_at y paused_by_expiration_at solo traen valor en instrucciones recurrent — son null para one_time y scheduled.

Errores:

CódigoMotivo
422 Unprocessable EntityEl 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_limit se rechaza en el POST inicial, pero no se vuelve a validar en un PATCH que suba el amount — ni si editas el max_amount_limit del 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 queda skipped en 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 pending igual 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 request

El intento de dispersión inmediata es best-effort: si el intento falla, tu POST/PATCH igual responde 201/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 instrucciones one_time

Una instrucción one_time solo puede eliminarse mientras sigue en estado scheduled (aún no se ejecutó). Si ya se ejecutó (completed) o falló (failed), el endpoint devuelve 422. Las instrucciones scheduled y recurrent no 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).

📘

priority no determina este orden

El campo priority solo 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), no priority.

Cada noche, Conekta evalúa las instrucciones que aplican para ese día en este orden:

  1. Instrucciones scheduled, luego recurrent, luego one_time — en ese orden de tipo, no mezcladas entre sí.
  2. Dentro de cada tipo, de menor a mayor monto (amount ascendente) — no por priority.

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ías

Lo 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_time de ayer que quedó pendiente se procesa antes que una scheduled de 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): si amount excede el max_amount_limit del beneficiario, la API responde 422 amount_exceeds_payee_limit de 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 estado skipped — nunca se intenta el envío a SPEI, y no cuenta como falla del batch. Ver Detalle de una dispersión.

max_amount_limit es obligatorio desde el alta

POST /payouts/payees rechaza 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_renewAl llegar end_date sin confirmarSe puede recuperar
false (default)La instrucción pasa a expiredterminal, no se puede reactivar. Tienes que crear una instrucción nueva.No
trueLa 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ódigoMotivo
422 Unprocessable EntityLa 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ódigoMotivo
422 Unprocessable EntityLa 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 reactivar

Una instrucción paused_by_expiration que no reactivas a tiempo pasa a archived de forma automática — terminal, sin ningún endpoint para revertirla. Si tu integración depende de auto_renew: true, no dejes pasar el periodo de gracia sin llamar a reactivate o confirm_renewal.

Related


Did this page help you?