También en markdown y en OpenAPI.

Referencia de la API de Makatea

Generada del OpenAPI de producción (versión 2026-09-27). URL base: https://makatea.ai/api. Las descripciones de rutas y campos vienen del spec, en inglés. Las guías en español están en https://makatea.ai/desarrolladores.

Introducción

The Makatea API lets your system create members and billing orders, register payments, and receive events. Every response carries Makatea-Version (the version applied to the request; the old name Makatea-API-Version carries the same value) and an X-Request-Id (send your own to correlate logs). Current version: 2026-09-27.

Versions

A version is a date. Which one applies to a request:

  1. the Makatea-Version: YYYY-MM-DD header, if you send it (an unknown version is 400 invalid_api_version);
  2. otherwise, the version pinned to your API key (the current one on the day the key was created — keys created before 2026-09-27 stay on 2026-09-23, so nothing changes for existing integrations);
  3. otherwise (session JWT), the latest.

Webhook endpoints have their own frozen version (webhook_version, set when the endpoint is created): the shape of an event never changes under you.

  • 2026-09-23: First public version: API keys, Idempotency-Key, cursor pagination, webhooks with signed bodies.
  • 2026-09-27: Request bodies: a field the operation does not declare is 422 unknown_field (it used to be ignored silently, like unknown query parameters before). Webhook events (endpoints on this version): the body carries api_version and livemode (false for events of a test organization).

Sync like an ERP

PUT /v1/members/by-ref/{external_ref}, PUT /v1/billing-orders/by-ref/{external_ref} and PUT /v1/credits/by-ref/{external_ref} create or update by your identifier: 201 created, 200 updated, 200 unchanged when everything you sent is already so (nothing is written); the header Makatea-Upsert-Result says which. POST /v1/members/batch, /v1/billing-orders/batch and /v1/payments/batch take up to 500 rows, never fail as a whole (one result per row, with its index and error code), support dry_run, and emit no webhooks and send no messages.

Authentication

Create an API key in Makatea → Settings → API. Send it in either header:

Authorization: Bearer mk_live_…      (or mk_test_…)
X-API-Key: mk_live_…

Test keys (mk_test_…) work exactly the same against your organization's test copy («<org> · pruebas», created with the first test key): same rules and engine, separate data, and nothing leaves — messages are recorded as simulated, there is no payment provider. Every response says Makatea-Livemode: true|false and webhook events of the test copy carry "livemode": false (version 2026-09-27 or later).

Keys have scopes: read (GET) and write (everything else). A session JWT from the Makatea app is also accepted in Authorization (legacy). Missing or invalid credentials → 401; a key without the needed scope → 403 insufficient_scope.

Responses

Success always has the same shape, for single objects and for lists:

{"data": {…} }
{"data": [ … ], "pagination": {"limit": 100, "has_more": true, "next_cursor": "eyJm…"}}

Errors always look like this:

{"error": {"code": "validation_error", "message": "amount must be a positive number", "request_id": "…"}}
StatusMeaning
400Malformed request: invalid JSON, unknown query parameter (unknown_parameter lists the allowed ones), bad cursor
401Missing/invalid credentials
403Key lacks the scope
404Not found (also unknown routes: route_not_found)
405Route exists with another method
409Conflict with the current state (already paid, duplicate external_ref, opted out, …)
413Body or document too large
422Validation error, or an Idempotency-Key reused with a different body
429Rate limit exceeded (see Retry-After)
5xxOur fault; safe to retry with the same Idempotency-Key

Pagination and sync

Lists accept limit (default 100, max 500) and cursor. Pass the next_cursor you received to get the next page, keeping the same filters; stop when has_more is false. offset still works for compatibility but can skip rows while data changes. Add count=true to get pagination.total (slower).

To mirror data into your system, call the list with updated_since=<last sync instant>: results come ordered by updated_at ascending, so you can page with the cursor and store the updated_at of the last row as your next checkpoint.

Idempotency

Send Idempotency-Key: <unique string> on any POST/PUT/PATCH/DELETE. Retrying with the same key and the same body returns the original response (with header Idempotent-Replayed: true) instead of acting twice. The same key with a different body is 422 idempotency_key_reused; while the first request is still running, 409 idempotency_in_progress. Keys are kept 24 hours.

Webhooks

Register an https endpoint (POST /v1/webhook-endpoints) with the event types you want (or *). The response includes the signing secret (whsec_…) only once. Each event is POSTed as:

{"id": "<event id>", "type": "payment.received", "created_at": "…", "data": {…}}

(endpoints on version 2026-09-27 or later also get "api_version" and "livemode"), with headers Makatea-Event-Id, Makatea-Event-Type, Makatea-Version (the endpoint's frozen version) and

Makatea-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>

Verify by recomputing the HMAC over t + "." + raw body and comparing in constant time; reject timestamps older than 5 minutes. Answer 2xx within 10 seconds. Otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 24 h; after 8 failed attempts the delivery is failed (you can retry it with POST /v1/webhook-deliveries/{id}/retry). Deliveries can arrive more than once or out of order: use the event id to de-duplicate.

Event types: member.created, member.updated, member.paused, member.resumed, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, payment_link.opened, promise.created, promise.kept, promise.broken, message.sent, message.received, message.classified. *.updated events carry {"object": {…}, "previous_attributes": {…}}. Records created by CSV imports do not emit events.

Limits

600 requests per minute per API key (per organization for session JWTs), in fixed one-minute windows. Every response includes the IETF headers (draft-ietf-httpapi-ratelimit-headers)

RateLimit-Policy: "default";q=600;w=60
RateLimit: "default";r=598;t=37

(q quota per w-second window, r remaining, t seconds until the window resets) and the older X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (unix seconds). Over the limit → 429 with Retry-After. A rejected request does not count: retrying while limited does not push the reset further. Request bodies up to 21 MB; documents up to 15 MB; batches up to 500 rows.

Error codes

Every operation lists the codes it can return, grouped by HTTP status (x-error-codes has the same as a map). The full catalog:

CodeStatusMeaning
already_delivered409The webhook delivery was already delivered.
already_voided409The payment was already voided.
amount_below_paid422The new amount is lower than what was already paid and forgiven.
amount_exceeds_balance422The payment is larger than the balance and excess is reject.
auth_unavailable503Could not verify the API key. Retry.
batch_too_large413More rows than the batch limit (500).
billing_orders_not_found422Some billing orders in the list do not exist (details.missing).
breakdown_exceeds_amount422capital_portion + interest_portion is larger than amount.
channel_unavailable503No connected line for that channel.
comms_disabled409Messaging is turned off for this organization.
conflict409A record with the same unique value (usually external_ref) already exists.
credit_member_mismatch422The credit belongs to another member.
credit_not_found422The credit referenced in the body (credit_id / credit_external_ref) does not exist.
do_not_contact409The member is marked «do not contact»: nothing is sent to them.
download_failed422The document URL could not be downloaded.
duplicate_in_batch422Another row of the same batch has this external_ref; only the first is processed.
external_ref_mismatch422external_ref in the body differs from the one in the path.
external_ref_reused409A payment with this external_ref exists with a different order or amount. Void it and send a new one.
flow_audience_not_editable409The flow's audience is defined by tags, segments or states, not by a member list.
flow_not_active409The flow is not active.
full_name_required422Creating a member needs full_name.
idempotency_in_progress409A request with the same Idempotency-Key is still running. Retry shortly.
idempotency_key_reused422The Idempotency-Key was already used with a different request body.
idempotency_unavailable503Could not record the Idempotency-Key. Retry.
immutable_field422The field can only be set when the record is created.
import_failed502The conversation import service failed.
insufficient_scope403The API key lacks the scope this operation needs (read for GET, write for the rest).
internal_error500Our fault. Safe to retry with the same Idempotency-Key.
invalid_api_key401The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.
invalid_api_version400The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.
invalid_cursor400The cursor is malformed or belongs to another ordering. Keep the same filters between pages.
invalid_idempotency_key400Idempotency-Key must be 1 to 255 characters.
invalid_json400The body is not valid JSON, is not an object, or is missing when required.
invalid_parameter400A query parameter has an invalid value (not a UUID, not a date, out of range).
invalid_reference422A referenced record does not exist.
member_mismatch409The external_ref belongs to a record of another member. Moving is explicit (PATCH with member_id).
member_not_found422The member referenced in the body (member_id / member_external_ref) does not exist.
method_not_allowed405The route exists with another method (see the Allow header).
no_active_promise409The member has no active payment promise.
no_org403Session JWT of a user that has not finished onboarding.
no_payment_provider409The organization has no active payment provider.
no_recipient422The member has no phone (WhatsApp/SMS) or no email (email).
not_found404The resource does not exist in your organization.
not_paused409The member is not paused.
not_voidable409Reversal entries cannot be voided.
nothing_to_forgive409The billing order has no balance to forgive.
opted_out409The member opted out of messages.
order_cancelled409The billing order is cancelled.
order_has_payments409The billing order has payments or forgiveness; only an untouched balance can be transferred.
order_not_found422The billing order referenced in the body does not exist.
order_not_open409The operation needs a pending or overdue billing order.
order_paid409The billing order is already paid.
outside_send_window409Outside the organization's send window.
payload_too_large413Body over 21 MB or document over 15 MB.
payment_link_unavailable502The payment provider could not create the link.
payment_voided409The Idempotency-Key belongs to a payment that was voided. A voided payment is not re-applied: send the new payment with a new key. details.payment_id is the voided one.
plan_limit_reached402Your plan's member limit is reached.
rate_limited429Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
reason_required422do_not_contact: true needs do_not_contact_reason.
route_not_found404No such route.
schedule_on_existing_credit409schedule only applies when the credit is created; it already has installments.
send_failed502The channel provider rejected the message.
split_breakdown_partially_paid409A billing order with a capital/interest breakdown and payments cannot be split; void the payments or remove the breakdown first.
split_sum_mismatch422The parts of a split do not add up to the balance to the cent (details.expected, details.got).
storage_error502The document could not be stored.
template_inactive409The template is not active.
transfer_not_allowed409The destination order is cancelled, paid (with add_to_destination), the same order, or belongs to another member.
unauthorized401Missing or invalid credentials.
unknown_field422A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.
unknown_parameter400A query parameter the route does not declare. details.allowed lists the valid ones.
validation_error422A field is missing or has an invalid value. details.field names it.

Status

GET /v1/status (no key) says whether the service and its database answer.

Índice de rutas

Status

GET /v1/status

Service status (no authentication).

Checks that the database answers. Returns 503 when it does not.

Respuestas

Members

GET /v1/members

List members.

Parámetros

NombreEnTipoObligatorioDescripción
statequerystring: contact, active, at_risk, delinquent, dormant, churned
qquerystringSearch in name or phone.
external_refquerystringExact match on your own identifier.
updated_sincequerystring (date-time)Only records changed at or after this instant (ISO-8601). Switches ordering to updated_at ascending, so you can resume a sync with the last next_cursor.
include_erasedquerybooleanInclude members erased for privacy (full_name «[titular eliminado]», no phone). They are not customers anymore: left out by default, like in the app.
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members

Create a member.

Two members may share a phone number. external_ref is unique per organization (409 if reused).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestringsí
first_namestring, nullableThe name used to greet the member ({{member_first_name}}). Without it, the first word of full_name.
phone_e164stringNormalized to E.164 (10 bare digits are read as Mexico; +521… becomes +52…). 422 if it is not a recognizable phone. Ejemplo: "+525512345678".
emailstring
statestring: contact, active, at_risk, delinquent, dormant, churnedPor omisión: "contact".
external_refstringYour identifier for this member.
identityobjectFree-form attributes (used as template variables).
tagsarray de string
notesstring
customer_sincestring (date)When the member became your customer (not when it entered Makatea). Not in the future.
do_not_contactbooleanNever send this member any message. Requires do_not_contact_reason. Por omisión: false.
do_not_contact_reasonstring

Respuestas

  • 201 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 402 plan_limit_reached — Your plan's member limit is reached.
  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

reason_required — do_not_contact: true needs do_not_contact_reason.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/members/{id}

Get a member (with billing orders and recent interactions).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PUT /v1/members/{id}

Update a member.

Only the fields you send are changed.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestring
first_namestring, nullableThe name used to greet the member ({{member_first_name}}). Without it, the first word of full_name.
phone_e164string, nullableNormalized to E.164; 422 if not a recognizable phone.
emailstring, nullable
statestring: contact, active, at_risk, delinquent, dormant, churned
external_refstring, nullable
identityobject
tagsarray de string
notesstring, nullable
customer_sincestring (date), nullableNot in the future. null clears it.
do_not_contactbooleantrue requires do_not_contact_reason (sent now or already on file); false clears the reason. Pending messages are withdrawn when it turns on.
do_not_contact_reasonstringCan be sent alone to change the reason of a member already marked.

Respuestas

  • 200 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

reason_required — do_not_contact: true needs do_not_contact_reason.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PATCH /v1/members/{id}

Update a member (partial).

Only the fields you send are changed.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestring
first_namestring, nullableThe name used to greet the member ({{member_first_name}}). Without it, the first word of full_name.
phone_e164string, nullableNormalized to E.164; 422 if not a recognizable phone.
emailstring, nullable
statestring: contact, active, at_risk, delinquent, dormant, churned
external_refstring, nullable
identityobject
tagsarray de string
notesstring, nullable
customer_sincestring (date), nullableNot in the future. null clears it.
do_not_contactbooleantrue requires do_not_contact_reason (sent now or already on file); false clears the reason. Pending messages are withdrawn when it turns on.
do_not_contact_reasonstringCan be sent alone to change the reason of a member already marked.

Respuestas

  • 200 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

reason_required — do_not_contact: true needs do_not_contact_reason.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

DELETE /v1/members/{id}

Soft-delete a member (state becomes churned).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Sync

PUT /v1/members/by-ref/{external_ref}

Create or update a member by your external_ref (upsert).

The member identified by external_ref (your id) ends up as the body says. Does not exist → created, 201. Exists and something changed → only the fields you sent are updated, 200. Exists and every field you sent is equal → nothing is written (not even updated_at), 200. The header Makatea-Upsert-Result says which (created, updated, unchanged). Fields you omit are not touched; null clears a nullable field. Emits member.created / member.updated like the other routes (a batch does not).

Parámetros

NombreEnTipoObligatorioDescripción
external_refpathstringsíYour identifier (URL-encode it).
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
external_refstringYour identifier: the upsert key (unique per organization).
full_namestringRequired to create.
first_namestring, nullableThe name used to greet the member ({{member_first_name}}). Without it, the first word of full_name.
phone_e164string, nullable
emailstring, nullable
statestring: contact, active, at_risk, delinquent, dormant, churnedDerived from the member's orders: contact (no orders), active (nothing overdue), delinquent (1 to 60 days late), dormant (more than 60). A new member starts as contact.
identityobjectReplaces the whole object.
tagsarray de stringReplaces the whole list.
notesstring, nullable
customer_sincestring (date), nullable
do_not_contactboolean
do_not_contact_reasonstring, nullable

Respuestas

  • 200 OK · data: Member
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 402 plan_limit_reached — Your plan's member limit is reached.
  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 external_ref_mismatch — external_ref in the body differs from the one in the path.

full_name_required — Creating a member needs full_name.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

reason_required — do_not_contact: true needs do_not_contact_reason.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members/batch

Create or update up to 500 members by external_ref.

Never fails as a whole: each row gets its own result (created, updated, unchanged or failed with error.code, error.message, error.field), in the same order and with its index (0-based). Rows are matched by external_ref; sending the same batch twice leaves the data exactly as it was (the second time every row is unchanged). A repeated external_ref inside one batch: the first row wins, the others fail with duplicate_in_batch. dry_run: true runs everything (locks, constraints, triggers) and rolls it back: the results are the ones you would get for real. Batches emit no webhooks and send no messages (the records carry import_batch_id = batch_id); single-row calls (PUT …/by-ref/…) do emit. Each row has the same fields as PUT /v1/members/by-ref/{external_ref} plus external_ref.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
dry_runbooleanPor omisión: false.
rowsarray de objectsí

Cada elemento de rows:

CampoTipoObligatorioDescripción
external_refstringsíYour identifier: the upsert key (unique per organization).
full_namestringRequired to create.
first_namestring, nullableThe name used to greet the member ({{member_first_name}}). Without it, the first word of full_name.
phone_e164string, nullable
emailstring, nullable
statestring: contact, active, at_risk, delinquent, dormant, churnedDerived from the member's orders: contact (no orders), active (nothing overdue), delinquent (1 to 60 days late), dormant (more than 60). A new member starts as contact.
identityobjectReplaces the whole object.
tagsarray de stringReplaces the whole list.
notesstring, nullable
customer_sincestring (date), nullable
do_not_contactboolean
do_not_contact_reasonstring, nullable

Respuestas

  • 200 OK · data: BatchResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 402 plan_limit_reached — Your plan's member limit is reached.
  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 413 batch_too_large — More rows than the batch limit (500).
  • 422 duplicate_in_batch — Another row of the same batch has this external_ref; only the first is processed.

full_name_required — Creating a member needs full_name.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

reason_required — do_not_contact: true needs do_not_contact_reason.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PUT /v1/billing-orders/by-ref/{external_ref}

Create or update a billing order by your external_ref (upsert).

Same contract as PUT /v1/members/by-ref/{external_ref}: 201 created, 200 updated or unchanged, header Makatea-Upsert-Result. To create, send member_id (or member_external_ref), amount and due_date. Updates go through the same path as PATCH /v1/billing-orders/{id} (moving due_date re-schedules its reminders, changing the breakdown re-applies its payments). An external_ref that belongs to another member's order is 409 member_mismatch (moving is explicit, with PATCH); cancelled orders are 409 order_cancelled.

Parámetros

NombreEnTipoObligatorioDescripción
external_refpathstringsíYour identifier (URL-encode it).
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
external_refstringYour identifier: the upsert key (unique per organization).
member_idstring (uuid)
member_external_refstringInstead of member_id.
amountnumberRequired to create.
due_datestring (date)Required to create.
currencystringOnly when created (immutable_field afterwards). Por omisión: "MXN".
period_labelstring, nullable
notesstring, nullable
capital_portionnumber, nullable
interest_portionnumber, nullable
credit_idstring (uuid), nullable
credit_external_refstring, nullableInstead of credit_id.

Respuestas

  • 200 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

member_mismatch — The external_ref belongs to a record of another member. Moving is explicit (PATCH with member_id).

order_cancelled — The billing order is cancelled.

  • 422 amount_below_paid — The new amount is lower than what was already paid and forgiven.

breakdown_exceeds_amount — capital_portion + interest_portion is larger than amount.

credit_member_mismatch — The credit belongs to another member.

credit_not_found — The credit referenced in the body (credit_id / credit_external_ref) does not exist.

external_ref_mismatch — external_ref in the body differs from the one in the path.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

immutable_field — The field can only be set when the record is created.

member_not_found — The member referenced in the body (member_id / member_external_ref) does not exist.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/batch

Create or update up to 500 billing orders by external_ref.

Never fails as a whole: each row gets its own result (created, updated, unchanged or failed with error.code, error.message, error.field), in the same order and with its index (0-based). Rows are matched by external_ref; sending the same batch twice leaves the data exactly as it was (the second time every row is unchanged). A repeated external_ref inside one batch: the first row wins, the others fail with duplicate_in_batch. dry_run: true runs everything (locks, constraints, triggers) and rolls it back: the results are the ones you would get for real. Batches emit no webhooks and send no messages (the records carry import_batch_id = batch_id); single-row calls (PUT …/by-ref/…) do emit. Each row has the same fields as PUT /v1/billing-orders/by-ref/{external_ref} plus external_ref. New orders are scheduled for collection like any other (the reminders are the calendar, not a notification).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
dry_runbooleanPor omisión: false.
rowsarray de objectsí

Cada elemento de rows:

CampoTipoObligatorioDescripción
external_refstringsíYour identifier: the upsert key (unique per organization).
member_idstring (uuid)
member_external_refstringInstead of member_id.
amountnumberRequired to create.
due_datestring (date)Required to create.
currencystringOnly when created (immutable_field afterwards). Por omisión: "MXN".
period_labelstring, nullable
notesstring, nullable
capital_portionnumber, nullable
interest_portionnumber, nullable
credit_idstring (uuid), nullable
credit_external_refstring, nullableInstead of credit_id.

Respuestas

  • 200 OK · data: BatchResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

member_mismatch — The external_ref belongs to a record of another member. Moving is explicit (PATCH with member_id).

order_cancelled — The billing order is cancelled.

  • 413 batch_too_large — More rows than the batch limit (500).
  • 422 amount_below_paid — The new amount is lower than what was already paid and forgiven.

breakdown_exceeds_amount — capital_portion + interest_portion is larger than amount.

credit_member_mismatch — The credit belongs to another member.

credit_not_found — The credit referenced in the body (credit_id / credit_external_ref) does not exist.

duplicate_in_batch — Another row of the same batch has this external_ref; only the first is processed.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

immutable_field — The field can only be set when the record is created.

member_not_found — The member referenced in the body (member_id / member_external_ref) does not exist.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PUT /v1/credits/by-ref/{external_ref}

Create or update a credit (loan) by its folio (upsert).

Same contract as the other by-ref routes: 201 created, 200 updated or unchanged, header Makatea-Upsert-Result. To create, send member_id (or member_external_ref), principal and start_date. A folio of another member is 409 member_mismatch. status accepts active or cancelled.

Parámetros

NombreEnTipoObligatorioDescripción
external_refpathstringsíYour identifier (URL-encode it).
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
member_idstring (uuid)
member_external_refstring
principalnumber
start_datestring (date)
total_amountnumber, nullable
periodsinteger, nullable
frequencystring: weekly, biweekly, semimonthly, monthly, daily, other, nullable
notesstring, nullable
statusstring: active, cancelled
scheduleobjectOnly when the PUT creates the credit (see POST /v1/credits). On an existing credit the same schedule is unchanged and a different one is 409 schedule_on_existing_credit.

Respuestas

  • 200 OK · data: LoanDetail
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

member_mismatch — The external_ref belongs to a record of another member. Moving is explicit (PATCH with member_id).

schedule_on_existing_credit — schedule only applies when the credit is created; it already has installments.

  • 422 external_ref_mismatch — external_ref in the body differs from the one in the path.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

member_not_found — The member referenced in the body (member_id / member_external_ref) does not exist.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/payments/batch

Register up to 500 payments (reconciliation).

Each row is one payment to one billing order (billing_order_id or billing_order_external_ref). The row's external_ref is your payment folio and makes the batch idempotent: a folio already registered with the same order and amount is unchanged (with its id), with a different order or amount it fails with external_ref_reused (void it and send a new folio). excess works like in POST /v1/billing-orders/{id}/payments. The ledger is append-only: payments are never updated. Rows run in order, so two payments to the same order see each other's effect. By default members are not notified (no «we received your payment» message) and no webhooks are emitted; send notify_members: true to send the organization's payment confirmations as if each payment came one by one. Never fails as a whole; dry_run rolls everything back.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
dry_runbooleanPor omisión: false.
notify_membersbooleanPor omisión: false.
rowsarray de objectsí

Cada elemento de rows:

CampoTipoObligatorioDescripción
external_refstringsíYour payment folio: the idempotency key. Same folio + same order and amount = unchanged; different = external_ref_reused.
billing_order_idstring (uuid)
billing_order_external_refstringInstead of billing_order_id.
amountnumbersí
paid_atstringWhen the money was received (date or ISO-8601; a date without time is that day in the organization's timezone). Default: now. Not in the future.
methodstring
referencestring
notesstring
excessstring: reject, creditPor omisión: "reject".

Respuestas

  • 200 OK · data: BatchResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 external_ref_reused — A payment with this external_ref exists with a different order or amount. Void it and send a new one.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_cancelled — The billing order is cancelled.

order_paid — The billing order is already paid.

  • 413 batch_too_large — More rows than the batch limit (500).
  • 422 amount_exceeds_balance — The payment is larger than the balance and excess is reject.

duplicate_in_batch — Another row of the same batch has this external_ref; only the first is processed.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

order_not_found — The billing order referenced in the body does not exist.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Promises

GET /v1/members/{id}/promises

Current promise and history.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: PromiseState
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members/{id}/promises

Record a payment promise.

Pauses collection messages until the promised date (one reminder survives). Replaces any active promise. When the date passes the promise becomes kept or broken (webhooks promise.kept / promise.broken).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
promised_datestring (date)sí
amountnumber

Respuestas

  • 201 OK · data: PromiseState
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

DELETE /v1/members/{id}/promises/current

Cancel the active promise.

Marks it cancelled (kept in history) and re-schedules collection for the member's open orders. 409 if there is no active promise.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: PromiseState
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

no_active_promise — The member has no active payment promise.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Collection control

POST /v1/members/{id}/pause

Pause collection for a member until a date.

Stops automatic collection and campaign messages to this member until until, through the same mechanism a payment promise uses: of the reminders due before until, only the one for the most serious delay survives (moved to until); the rest are withdrawn, and nothing new is scheduled before until. Event notices (payment confirmations) and explicit sends (POST /v1/messages) still go out. until as a date (2026-10-10) means 08:00 in the organization's timezone that day; a date-time without offset is local time. Pausing an already paused member replaces the date. When until passes, collection simply resumes (no call needed). Emits member.paused.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
untilstringsíDate (YYYY-MM-DD) or ISO-8601 timestamp. Future, at most 1 year ahead. Ejemplo: "2026-10-10".
reasonstringWhy (shown in the app and in the event).

Respuestas

  • 200 OK · data: PauseState
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members/{id}/resume

Resume collection now (end a pause early).

Ends the pause. The reminder that was waiting for the end of the pause is moved to the member's next decent hour (08:00–22:00 local, otherwise the next morning), and the reminders the pause withdrew that are still in the future are scheduled again. 409 not_paused if there is no active pause. Emits member.resumed.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: PauseState
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

not_paused — The member is not paused.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/flows/{id}/members

Enroll a member in a flow (flows whose audience is a member list).

Adds the member to the flow's explicit audience list and, if the flow is active, schedules its messages right away (idempotent: enrolling twice changes nothing). Only flows with audience_mode: members have a list; a flow whose audience is defined by tags, segments or states answers 409 flow_audience_not_editable (membership there follows that criterion: change the member's tags or state instead).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
member_idstring (uuid)sí

Respuestas

  • 200 OK · data: FlowMembership
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 flow_audience_not_editable — The flow's audience is defined by tags, segments or states, not by a member list.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

DELETE /v1/flows/{id}/members/{member_id}

Remove a member from a flow (member-list flows).

Removes the member from the flow's list and withdraws its pending messages of that flow. Same 409 flow_audience_not_editable rule as enrolling.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
member_idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: FlowMembership
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 flow_audience_not_editable — The flow's audience is defined by tags, segments or states, not by a member list.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Credit

GET /v1/members/{id}/credit

Credit balance and its ledger.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: Credit
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members/{id}/credit/apply

Apply the credit balance to open orders (oldest first).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: CreditApplied
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Messages

GET /v1/members/{id}/conversation

Messages exchanged with a member (newest first).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
channelquerystring: whatsapp, sms, email
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Interaction
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/messages

Send a message to a member.

With text: sent right away through the organization's line (WhatsApp or SMS) — status: sent.

With template_id: queued for the sending engine, which renders the template variables — status: queued (any channel, including email).

Respects opt-outs (409 opted_out), the organization's kill switch (409 comms_disabled) and its send window (409 outside_send_window, text only; queued messages wait for the window).

Organizations in simulation mode record the message but nothing leaves (status: simulated).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
member_idstring (uuid)sí
channelstring: whatsapp, sms, emailPor omisión: "whatsapp".
textstring
template_idstring (uuid)

Respuestas

  • 202 OK · data: MessageResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 comms_disabled — Messaging is turned off for this organization.

do_not_contact — The member is marked «do not contact»: nothing is sent to them.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

opted_out — The member opted out of messages.

outside_send_window — Outside the organization's send window.

template_inactive — The template is not active.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

no_recipient — The member has no phone (WhatsApp/SMS) or no email (email).

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.
  • 502 send_failed — The channel provider rejected the message.
  • 503 channel_unavailable — No connected line for that channel.

POST /v1/conversations/import

Import conversation history (messages that happened outside Makatea).

Up to 20,000 rows per call. Idempotent by external_id (or by member + time + direction + text). Imported messages trigger nothing: no auto-replies, no notices, no webhooks. dry_run validates without writing. Members are matched by member_external_ref, or by phone when exactly one member has it. Re-sending a row that was imported without its attachment completes it.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
dry_runboolean
rowsarray de object

Cada elemento de rows:

CampoTipoObligatorioDescripción
member_external_refstring
phonestring
occurred_atstring (date-time)sí
directionstring: inbound, outboundsí
channelstring: whatsapp, email, smssí
bodystringsí
subjectstring
external_idstring
media_urlstringhttps link to the attachment (photo, voice note, sticker, video, document). Makatea downloads and stores it (max 20 MB). Requires external_id; body may then be empty.
media_mimestring
media_namestring
reactionsarray de object

Respuestas

  • 200 OK · data: ConversationImportResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 413 payload_too_large — Body over 21 MB or document over 15 MB.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.
  • 502 import_failed — The conversation import service failed.

Documents

GET /v1/members/{id}/documents

List a member's documents (with temporary download URLs, valid 1 hour).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
external_refquerystringExact match on your own identifier.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Document
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/members/{id}/documents

Attach a document to a member.

Send the file inline (content_base64) or a public https url the server downloads. Max 15 MB. With external_ref, repeating the call returns the existing document (200) instead of uploading twice.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
namestringsí
mime_typestring
content_base64string (byte)
urlstring (uri)
external_refstring
typestring: ine_frontal, ine_reverso, comprobante, otroPor omisión: "otro".
descriptionstring

Respuestas

  • 201 OK · data: Document
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 413 payload_too_large — Body over 21 MB or document over 15 MB.
  • 422 download_failed — The document URL could not be downloaded.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.
  • 502 storage_error — The document could not be stored.

DELETE /v1/members/{id}/documents/{document_id}

Delete a document (file and record).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
document_idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Deleted
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Billing orders

GET /v1/billing-orders

List billing orders.

Default order: due_date ascending. With updated_since: updated_at ascending.

Parámetros

NombreEnTipoObligatorioDescripción
statusquerystring: pending, overdue, paid, cancelled
member_idquerystring (uuid)
external_refquerystringExact match on your own identifier.
updated_sincequerystring (date-time)Only records changed at or after this instant (ISO-8601). Switches ordering to updated_at ascending, so you can resume a sync with the last next_cursor.
credit_idquerystring (uuid)Only the installments of this credit.
due_fromquerystring (date)
due_toquerystring (date)
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders

Create a billing order.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
member_idstring (uuid)sí
amountnumbersí
currencystringPor omisión: "MXN".
due_datestring (date)sí
period_labelstring
external_refstringUnique per organization.
notesstring
capital_portionnumber, nullablePrincipal part of this installment. Send together with interest_portion (both null removes the breakdown). capital + interest ≤ amount; the rest of amount is the collectible late fee and, beyond it, «other charges».
interest_portionnumber, nullableInterest part of this installment (include commissions you consider interest).
credit_idstring (uuid), nullableCredit (loan) this installment belongs to; must be of the same member. null detaches it.

Respuestas

  • 201 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 breakdown_exceeds_amount — capital_portion + interest_portion is larger than amount.

credit_member_mismatch — The credit belongs to another member.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/billing-orders/{id}

Get a billing order.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PATCH /v1/billing-orders/{id}

Update a billing order (move the date, change the amount, …).

Moving due_date re-schedules its collection messages. Raising amount above what was paid re-opens a paid order; lowering it to what is covered marks it paid. late_fee sets the accumulated late fee (absolute). capital_portion/interest_portion set the breakdown (also on paid orders: it is history) and re-apply the order's payments. Cancelled orders cannot be edited (409).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
due_datestring (date)
amountnumber
period_labelstring, nullable
late_feenumber
external_refstring, nullable
notesstring, nullable
member_idstring (uuid)Move the order (with its payments) to another member of the organization.
capital_portionnumber, nullablePrincipal part of this installment. Send together with interest_portion (both null removes the breakdown). capital + interest ≤ amount; the rest of amount is the collectible late fee and, beyond it, «other charges».
interest_portionnumber, nullableInterest part of this installment (include commissions you consider interest).
credit_idstring (uuid), nullableCredit (loan) this installment belongs to; must be of the same member. null detaches it.

Respuestas

  • 200 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_cancelled — The billing order is cancelled.

  • 422 amount_below_paid — The new amount is lower than what was already paid and forgiven.

breakdown_exceeds_amount — capital_portion + interest_portion is larger than amount.

credit_member_mismatch — The credit belongs to another member.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

DELETE /v1/billing-orders/{id}

Cancel a billing order (409 if already paid).

Optional reason (query ?reason= or JSON body {"reason": …}, max 500 chars) is stored as cancel_reason — e.g. «consolidated into another account». Cancelling an already cancelled order with a reason updates the reason.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
reasonquerystringWhy the order is cancelled (stored as cancel_reason).
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
reasonstring

Respuestas

  • 200 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_paid — The billing order is already paid.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/transfer

Transfer an installment's balance to another installment of the same member.

For a debt that is now collected elsewhere (restructure, consolidation into a new loan). The origin must be open and untouched (no payments, no forgiveness); it becomes cancelled with transferred_to_order_id and cancel_reason (reason or «Traspasada a <destination>»), and its collection stops. Its credit is liquidated by itself when nothing else of it is open. The destination's amount does not change unless add_to_destination is true (when your system did not already include it). Repeating the same transfer answers 200 with already_transferred. Do not send an amount of 0 to say this: amounts must be positive.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
to_order_idstring (uuid)
to_order_external_refstringYour folio of the destination installment (same member).
reasonstring
add_to_destinationbooleanPor omisión: false.

Respuestas

  • 200 OK · data: TransferResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_has_payments — The billing order has payments or forgiveness; only an untouched balance can be transferred.

order_not_open — The operation needs a pending or overdue billing order.

transfer_not_allowed — The destination order is cancelled, paid (with add_to_destination), the same order, or belongs to another member.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

order_not_found — The billing order referenced in the body does not exist.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/split

Split a billing order into several (explicit parts or generated installments).

Splits what is still owed (amount − amount_paid − amount_forgiven) into new billing orders of the same member, credit and currency, each with parent_order_id = this one. Either send parts (2 to 60 {amount, due_date, period_label?, external_ref?} that must add up exactly to the balance, else 422 split_sum_mismatch with details.expected), or installments (2 to 60) + frequency (default monthly) + first_due_date (default: the order's due date, or today in the organization's timezone if that already passed): the balance is split to the cent and the last one absorbs the rounding. The original is kept as history: with nothing paid it becomes cancelled (cancel_reason = reason or «Dividida en N partes»); with partial payments its amount is lowered to what was covered and it becomes paid. A breakdown (capital/interest) is split proportionally; an order with a breakdown and payments cannot be split (409 split_breakdown_partially_paid). Only pending/overdue orders (409 order_not_open).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
partsarray de object
installmentsinteger
frequencystring: weekly, biweekly, semimonthly, monthlyPor omisión: "monthly".
first_due_datestring (date)
reasonstring

Cada elemento de parts:

CampoTipoObligatorioDescripción
amountnumbersí
due_datestring (date)sí
period_labelstring
external_refstring

Respuestas

  • 201 OK · data: SplitResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_not_open — The operation needs a pending or overdue billing order.

split_breakdown_partially_paid — A billing order with a capital/interest breakdown and payments cannot be split; void the payments or remove the breakdown first.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

split_sum_mismatch — The parts of a split do not add up to the balance to the cent (details.expected, details.got).

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/forgive

Forgive (condone) part or all of the balance.

Forgiven money is not a payment: it does not appear in /v1/payments. Without amount, forgives the whole balance and the order becomes paid. On orders with a breakdown the forgiveness takes, of what is still owed, late fee first, then interest, then other charges and principal last (forgiven_now_breakdown; forgiven principal is a loss).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
amountnumber
reasonstring

Respuestas

  • 200 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

nothing_to_forgive — The billing order has no balance to forgive.

order_cancelled — The billing order is cancelled.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/late-fees

Add a late fee to an order.

Adds to late_fee and fires the late_fee_applied notice if the organization configured one. With collectible: true the fee is also added to amount (it becomes owed; a paid order re-opens). When omitted, the organization's moratorio_cobrable setting decides (default: informational only).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
amountnumbersí
collectibleboolean

Respuestas

  • 201 OK · data: BillingOrder
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_cancelled — The billing order is cancelled.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/payment-link

Create (or reuse) a payment link, optionally send it to the member.

Creates the link with the organization's payment provider, or returns the current one if it has not expired (url: Stripe Checkout, or Makatea's page for OXXO/SPEI references). page_url is always Makatea's payment page for this order (/pagar/<token>): it works with any provider and its opens are observable — each open emits payment_link.opened (deduplicated per link in a 10-minute window, no personal data) and is counted in opens.count / opens.last_opened_at.

expires_at asks for a validity; it is bounded to what the provider accepts (Stripe 30 min – 24 h, Conekta 1 h – 30 days) and the response carries the real one. Asking for a different validity than the current link's creates a new link.

The link charges the order's open balance (amount − paid − forgiven) in the order's currency. Providers by currency: Stripe, any currency; Conekta, MXN only; Pix, BRL orders of an organization with a Pix key (Pix comes first for BRL, even with Stripe connected; provider: "pix", no expiry). A new link is created when the balance or the currency changed since the current one.

send_via (whatsapp, sms or email) also sends page_url to the member right away, with the same rules as POST /v1/messages (opt-outs, «do not contact», kill switch, send window for WhatsApp/SMS, simulation mode). Nothing is sent without a payment provider for the order's currency (409 no_payment_provider) or for a paid/cancelled order (409 order_not_open). The link is created even if the send fails: the error says why it was not sent.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
send_viastring: whatsapp, sms, email
expires_atstring (date-time)Desired validity (future). Bounded per provider.

Respuestas

  • 200 OK · data: PaymentLink
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 comms_disabled — Messaging is turned off for this organization.

do_not_contact — The member is marked «do not contact»: nothing is sent to them.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

no_payment_provider — The organization has no active payment provider.

opted_out — The member opted out of messages.

order_not_open — The operation needs a pending or overdue billing order.

outside_send_window — Outside the organization's send window.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

no_recipient — The member has no phone (WhatsApp/SMS) or no email (email).

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.
  • 502 payment_link_unavailable — The payment provider could not create the link.

send_failed — The channel provider rejected the message.

  • 503 channel_unavailable — No connected line for that channel.

Payments

POST /v1/billing-orders/{id}/pay

Settle the whole remaining balance.

Registers one payment for exactly the remaining balance. For partial or historical payments use POST /v1/billing-orders/{id}/payments.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
methodstringPor omisión: "external".
typestringOld name of method.
referencestring
notesstring
paid_atstringWhen the money was received. Defaults to now. A date without time (2026-09-22) means that day in the organization's timezone (organizations.timezone): today → now, any other day → 12:00 local that day, so it never shifts to the previous day. A date and time without offset (2026-09-22T23:30) is that wall-clock time in the organization's timezone. A full ISO-8601 timestamp with Z or an offset is taken as is. Cannot be in the future. Ejemplo: "2026-09-22".

Respuestas

  • 200 OK · data: PaymentResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_cancelled — The billing order is cancelled.

order_paid — The billing order is already paid.

payment_voided — The Idempotency-Key belongs to a payment that was voided. A voided payment is not re-applied: send the new payment with a new key. details.payment_id is the voided one.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/billing-orders/{id}/payments

Register a payment (partial, historical date, overpayment policy).

excess decides what happens when amount is larger than the balance: reject (default) answers 422 amount_exceeds_balance; credit applies the excess to the member's next open orders (oldest first) and keeps the rest as credit balance.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
amountnumbersí
paid_atstringWhen the money was received. Defaults to now. A date without time (2026-09-22) means that day in the organization's timezone (organizations.timezone): today → now, any other day → 12:00 local that day, so it never shifts to the previous day. A date and time without offset (2026-09-22T23:30) is that wall-clock time in the organization's timezone. A full ISO-8601 timestamp with Z or an offset is taken as is. Cannot be in the future. Ejemplo: "2026-09-22".
methodstringEjemplo: "transfer".
referencestring
notesstring
excessstring: reject, creditPor omisión: "reject".

Respuestas

  • 201 OK · data: PaymentResult
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

order_cancelled — The billing order is cancelled.

payment_voided — The Idempotency-Key belongs to a payment that was voided. A voided payment is not re-applied: send the new payment with a new key. details.payment_id is the voided one.

  • 422 amount_exceeds_balance — The payment is larger than the balance and excess is reject.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/payments

List payments (the ledger).

Every money movement: payments (kind: payment) and reversals of voided payments (kind: reversal, negative amount). allocation says how each entry was applied to its installment (principal, interest, late fee, other charges, unassigned; null when the installment has no breakdown); a reversal carries exactly the same figures, negative. paid_at is when the money was received (it can be in the past); recorded_at is when the entry reached Makatea — created_since/updated_since and the ordering use recorded_at, so a back-dated payment registered today still shows up in your next sync. The ledger is append-only, so updated_since is an alias of created_since. Default order: newest first; with a *_since filter: oldest first.

Parámetros

NombreEnTipoObligatorioDescripción
member_idquerystring (uuid)
billing_order_idquerystring (uuid)
created_sincequerystring (date-time)Only records created at or after this instant (ISO-8601). Ordering becomes created_at ascending.
updated_sincequerystring (date-time)Only records changed at or after this instant (ISO-8601). Switches ordering to updated_at ascending, so you can resume a sync with the last next_cursor.
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Payment
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/payments/{id}

Get a payment.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: Payment
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/payments/{id}/void

Void a payment.

Writes a reversal (negative) entry, lowers the order's amount_paid and re-opens it if needed. 409 already_voided the second time.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
reasonstring

Respuestas

  • 200 OK · data: Payment
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 already_voided — The payment was already voided.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

not_voidable — Reversal entries cannot be voided.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Credits (loans)

GET /v1/credits

List credits (loans) with their principal, what came back and what is owed.

Each credit groups the installments of one loan (external_ref = your folio) and carries its principal. totals are to date: capital_recovered/interest_collected/late_fee_collected = what the payment ledger applied to its installments (voided payments net out); capital_outstanding/interest_outstanding = of its open installments with breakdown; balance = amount − paid − forgiven of its open installments; paid_without_ledger = paid amounts imported as history, with no ledger entry. Default order: start_date descending; with updated_since: updated_at ascending.

Parámetros

NombreEnTipoObligatorioDescripción
member_idquerystring (uuid)
external_refquerystringExact match on your own identifier.
updated_sincequerystring (date-time)Only records changed at or after this instant (ISO-8601). Switches ordering to updated_at ascending, so you can resume a sync with the last next_cursor.
statusquerystring: active, liquidated, cancelled
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Loan
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/credits

Create a credit (loan): generate its installments or attach existing ones.

external_ref (your folio) is unique per organization: reusing it is 409. start_date is when the money was lent: it decides in which period the principal counts as «placed».

Generate the installments with schedule: installments payments, frequency weekly (+7 days), biweekly (+14 days), semimonthly (the 15th and the last day of each month; a first_due_date on another day moves to the next of the two) or monthly (same day each month, or day_of_month; a day the month lacks becomes its last day: Jan 31 → Feb 28 → Mar 31), starting at first_due_date (default: one period after start_date). Amounts: installment_amount each (total = n × amount), otherwise total_amount split in n, otherwise principal split in n. Split exactly to the cent: the first ones get the floor and the last one absorbs the rounding (1,000 / 3 = 333.33 + 333.33 + 333.34). When both principal and total are known each installment carries its capital/interest breakdown (the interest is total − principal, split the same way). Installments are labeled «Pago i de n» and, if the credit has a folio, get external_ref = <folio>-<i>. All or nothing: if they cannot be created the credit is not created either.

Attach existing installments instead by id or external_ref; they must belong to the same member (422 credit_member_mismatch).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
member_idstring (uuid)sí
external_refstringYour folio / contract number. Unique per organization.
principalnumbersíMoney lent (capital prestado).
start_datestring (date)síDate the money was lent.
total_amountnumberTotal the member will pay (principal + interest), if you have it.
periodsinteger
frequencystring: weekly, biweekly, semimonthly, monthly, daily, other
notesstring
billing_order_idsarray de string (uuid)
billing_order_external_refsarray de string
scheduleobjectGenerate the installments (see the operation description).

Respuestas

  • 201 OK · data: LoanDetail
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 billing_orders_not_found — Some billing orders in the list do not exist (details.missing).

credit_member_mismatch — The credit belongs to another member.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/credits/{id}

Get a credit with its installments and their breakdown.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: LoanDetail
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PATCH /v1/credits/{id}

Update a credit, attach or detach installments.

Only the fields you send change. status can be set to cancelled (the principal stops counting as placed) or back to active; liquidated is computed from its installments.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
external_refstring, nullable
principalnumber
start_datestring (date)
total_amountnumber, nullable
periodsinteger, nullable
frequencystring: weekly, biweekly, semimonthly, monthly, daily, other, nullable
notesstring, nullable
statusstring: active, cancelled
add_billing_order_idsarray de string (uuid)
add_billing_order_external_refsarray de string
remove_billing_order_idsarray de string (uuid)

Respuestas

  • 200 OK · data: LoanDetail
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 billing_orders_not_found — Some billing orders in the list do not exist (details.missing).

credit_member_mismatch — The credit belongs to another member.

idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/settings/payment-allocation

How payments are split between late fee, interest and principal.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: AllocationRule
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PUT /v1/settings/payment-allocation

Change the payment allocation rule.

moratorio_interes_capital (default: late fee, then interest, then other charges, then principal), proporcional (each payment split in proportion to what is owed of each part) or al_liquidar (a partial payment stays «unassigned» until the installment is settled; the settling payment recognizes all of its principal and interest on its date). The rule is fixed on each installment when its breakdown is loaded; with apply_existing: true every installment with breakdown is re-applied with the new rule (past figures change).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
rulestring: moratorio_interes_capital, proporcional, al_liquidarsí
apply_existingbooleanPor omisión: false.

Respuestas

  • 200 OK · data: AllocationRule
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Settings

GET /v1/settings/branding

Whether messages and pages carry «Cobrado con Makatea».

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: Branding
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

PUT /v1/settings/branding

Show or hide «Cobrado con Makatea» (on by default).

Controls the footer of collection emails («Cobrado con Makatea · makatea.ai»; other emails say «Enviado con Makatea») and the Makatea mark on the payment page (/pagar/<token>). On by default.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
makatea_brandingbooleansí

Respuestas

  • 200 OK · data: Branding
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Webhooks

GET /v1/webhook-endpoints

List webhook endpoints.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de WebhookEndpoint
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/webhook-endpoints

Register a webhook endpoint (the signing secret is returned only here).

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
urlstring (uri)síhttps only; private/internal hosts are rejected.
eventsarray de string: *, member.created, member.updated, member.paused, member.resumed, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, payment_link.opened, promise.created, promise.kept, promise.broken, message.sent, message.received, message.classifiedsí
descriptionstring
api_versionstring: 2026-09-23, 2026-09-27Version of the event bodies this endpoint receives, frozen at creation. Default: the version of this request.

Respuestas

  • 201 OK · data: WebhookEndpointCreated
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 409 conflict — A record with the same unique value (usually external_ref) already exists.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

unknown_field — A body field the operation does not accept (API version 2026-09-27 or later). details.field names it.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

DELETE /v1/webhook-endpoints/{id}

Delete a webhook endpoint (its pending deliveries are dropped).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Deleted
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.
  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/webhook-events

List emitted events (newest first).

Events are recorded only while the organization has at least one active endpoint subscribed to that type.

Parámetros

NombreEnTipoObligatorioDescripción
typequerystring
created_sincequerystring (date-time)Only records created at or after this instant (ISO-8601). Ordering becomes created_at ascending.
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de WebhookEvent
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/webhook-deliveries

List delivery attempts (newest first).

Parámetros

NombreEnTipoObligatorioDescripción
statusquerystring: pending, delivered, failed
event_idquerystring (uuid)
endpoint_idquerystring (uuid)
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de WebhookDelivery
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

POST /v1/webhook-deliveries/{id}/retry

Retry a delivery now (pending or failed).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: WebhookDelivery
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_idempotency_key — Idempotency-Key must be 1 to 255 characters.

invalid_json — The body is not valid JSON, is not an object, or is missing when required.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 404 not_found — The resource does not exist in your organization.
  • 409 already_delivered — The webhook delivery was already delivered.

idempotency_in_progress — A request with the same Idempotency-Key is still running. Retry shortly.

  • 422 idempotency_key_reused — The Idempotency-Key was already used with a different request body.

validation_error — A field is missing or has an invalid value. details.field names it.

  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Operations

GET /v1/sequence-runs

List scheduled/sent collection messages (newest scheduled first).

Parámetros

NombreEnTipoObligatorioDescripción
statequerystring
member_idquerystring (uuid)
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de SequenceRun
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_cursor — The cursor is malformed or belongs to another ordering. Keep the same filters between pages.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/flows

List the organization's flows.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Flow
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/templates

List the organization's active templates.

Parámetros

NombreEnTipoObligatorioDescripción
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: array de Template
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

GET /v1/stats

Dashboard numbers — the same figures the app's Panel shows.

Every money figure comes from the same database function the app uses (org_metricas_cobranza), so the API and the Panel never disagree. metrics has the full set for the period (from/to, default: 1st of the current month to today, in the org's timezone): collected = money that came in by payment date (voided payments, credit-balance applications and future-dated rows excluded), overdue/upcoming = real balance (amount − paid − forgiven) of open installments due before / on-or-after today, aging by days late (1-9, 10-30, 31-60, 60+), collection_rate = of what came due in the period up to today, the share already paid. metrics.capital_profit splits the same period into principal and profit: placed (principal lent, by credit start_date), collected.capital|interest|late_fee|other|unassigned|no_breakdown|to_credit_balance (they add up exactly to collected.total, the same «collected» as above), profit = interest + late fee collected with its margin over what was collected with a breakdown, outstanding principal and interest (current / overdue) of open installments, and forgiven split into principal (a loss), interest, late fee and other. coverage.status is none when no installment has a breakdown: then every figure is 0 and no_breakdown carries the money. portfolio and members keep their old shape.

Parámetros

NombreEnTipoObligatorioDescripción
fromquerystring (date)Period start (YYYY-MM-DD). Default: 1st of the current month.
toquerystring (date)Period end (YYYY-MM-DD). Default: today (org timezone).
Makatea-Versionheaderstring: 2026-09-23, 2026-09-27Version for this request (default: the one pinned to your key).

Respuestas

  • 200 OK · data: Stats
  • 400 invalid_api_version — The Makatea-Version header names a version that does not exist. details.versions lists the valid ones.

invalid_parameter — A query parameter has an invalid value (not a UUID, not a date, out of range).

unknown_parameter — A query parameter the route does not declare. details.allowed lists the valid ones.

  • 401 invalid_api_key — The API key (mk_live_… or mk_test_…) does not exist, was revoked or expired.

unauthorized — Missing or invalid credentials.

  • 403 insufficient_scope — The API key lacks the scope this operation needs (read for GET, write for the rest).
  • 429 rate_limited — Over the per-minute limit. Wait Retry-After seconds. Rejected requests do not count against the limit.
  • 500 internal_error — Our fault. Safe to retry with the same Idempotency-Key.

Objetos

ErrorBody

CampoTipoObligatorioDescripción
codestringsíStable code (see «Error codes»). Ejemplo: "validation_error".
messagestringsí
request_idstringsí
detailsobjectExtra context, e.g. field for validation errors.

Error

CampoTipoObligatorioDescripción
errorErrorBodysí

Pagination

CampoTipoObligatorioDescripción
limitinteger
has_moreboolean
next_cursorstring, nullable
offsetintegerOnly when paging with offset.
totalintegerOnly with count=true.

Status

CampoTipoObligatorioDescripción
statusstring: ok, degraded
databasestring
database_latency_msinteger
api_versionstring
timestring (date-time)

Member

CampoTipoObligatorioDescripción
idstring (uuid)
external_refstring, nullable
full_namestring
first_namestring, nullableGreeting name ({{member_first_name}}); null = first word of full_name.
phone_e164string, nullable
emailstring, nullable
statestring
identityobject
tagsarray de string
notesstring, nullable
payment_referencestring, nullable
segment_idstring, nullable
promised_datestring (date), nullable
promise_statusstring
promised_amountnumber, nullable
promise_registered_atstring (date-time), nullable
credit_balancenumber
do_not_contactbooleanNever message this member (withdraws anything queued).
do_not_contact_reasonstring, nullable
customer_sincestring (date), nullableWhen it became your customer; created_at is when it entered Makatea.
import_batch_idstring (uuid), nullable
paused_untilstring (date-time), nullableCollection paused until this instant (in the past = not paused).
pause_reasonstring, nullable
paused_atstring (date-time), nullable
created_atstring (date-time)
updated_atstring (date-time)

BillingOrder

CampoTipoObligatorioDescripción
idstring (uuid)
member_idstring (uuid)
external_refstring, nullable
amountnumber
amount_paidnumber
amount_forgivennumber
late_feenumber
balancenumberamount − amount_paid − amount_forgiven (late fees are reported apart).
currencystring
due_datestring (date)
period_labelstring, nullable
statusstring: pending, overdue, paid, cancelled
paid_atstring (date-time), nullable
paid_viastring, nullable
notesstring, nullable
forgiven_atstring (date-time), nullable
forgiven_reasonstring, nullable
cancel_reasonstring, nullableWhy it was cancelled (DELETE …?reason=).
created_atstring (date-time)
updated_atstring (date-time)
transferred_to_order_idstring (uuid), nullableInstallment its balance was transferred to (POST …/transfer); set only on cancelled orders.
credit_idstring (uuid), nullableCredit (loan) it belongs to.
capital_portionnumber, nullablePrincipal part of the installment (null = no breakdown).
interest_portionnumber, nullableInterest part of the installment.
breakdownobject, nullablenull when the installment has no breakdown (figures are never invented).

Payment

CampoTipoObligatorioDescripción
idstring (uuid)
billing_order_idstring (uuid)
member_idstring (uuid)
amountnumber
kindstring: payment, reversal
methodstring, nullable
referencestring, nullable
notesstring, nullable
voids_payment_idstring (uuid), nullable
voidedboolean
paid_atstring (date-time)When the money was received.
created_atstring (date-time)
recorded_atstring (date-time)When the entry was recorded in Makatea.
allocationobject, nullableHow this entry was applied to its installment. Adds up to amount. unassigned = beyond the installment's parts or, with rule al_liquidar, a partial payment not yet recognized (the settling payment then carries it negative). null when the installment has no breakdown.

TransferResult

CampoTipoObligatorioDescripción
already_transferredboolean
fromBillingOrder
toBillingOrder

PaymentResult

CampoTipoObligatorioDescripción
order_idstring (uuid)
amount_paidnumber
statusstring
fully_paidboolean
excess_applied_to_other_ordersnumber
credit_addednumber
already_appliedboolean
payment_idstring (uuid), nullableThe ledger entry of this call (or the original one when already_applied).
paymentPayment
orderBillingOrder

PromiseState

CampoTipoObligatorioDescripción
member_idstring (uuid)
statusstring: none, active, kept, broken, cancelled
currentobject, nullable
historyarray de object

Credit

CampoTipoObligatorioDescripción
member_idstring (uuid)
credit_balancenumber
ledgerarray de object

CreditApplied

CampoTipoObligatorioDescripción
member_idstring (uuid)
appliednumber
credit_balancenumber

Interaction

CampoTipoObligatorioDescripción
idstring (uuid)
channelstring
directionstring: inbound, outbound
textstring, nullable
attachmentstring, nullable
classificationstring, nullable
sequence_run_idstring (uuid), nullable
simulatedboolean
occurred_atstring (date-time)

MessageResult

CampoTipoObligatorioDescripción
idstring (uuid)
objectstring: interaction, sequence_run
statusstring: sent, simulated, queued, queued_simulated
channelstring
member_idstring (uuid)

ConversationImportResult

CampoTipoObligatorioDescripción
insertedinteger
skipped_duplicatesinteger
unmatchedarray de object
errorsarray de object

Document

CampoTipoObligatorioDescripción
idstring (uuid)
member_idstring (uuid)
namestring
typestring
mime_typestring
sizeinteger
external_refstring, nullable
descriptionstring, nullable
storage_pathstring
download_urlstring, nullableSigned URL, valid 1 hour.
download_url_expires_atstring (date-time), nullable
created_atstring (date-time)

Deleted

CampoTipoObligatorioDescripción
idstring (uuid)
deletedboolean
CampoTipoObligatorioDescripción
urlstring, nullableProvider link (Stripe Checkout) or Makatea's page (OXXO/SPEI). null without a provider (reason).
expires_atstring (date-time), nullableReal validity (bounded per provider).
expires_at_requestedstring (date-time)Only when you sent expires_at.
providerstring, nullable
reasonstringWhy there is no url (no_provider, order_closed, …).
page_urlstringMakatea's payment page for this order; its opens emit payment_link.opened.
opensobject
sentobject, nullableOnly with send_via.

Branding

CampoTipoObligatorioDescripción
makatea_brandingbooleantrue = «Cobrado con Makatea» in collection emails and on the payment page.

WebhookEndpoint

CampoTipoObligatorioDescripción
idstring (uuid)
urlstring
eventsarray de string
activeboolean
descriptionstring, nullable
webhook_versionstringVersion of the event bodies it receives (frozen).
created_atstring (date-time)
updated_atstring (date-time)

WebhookEndpointCreated

object

WebhookEvent

CampoTipoObligatorioDescripción
idstring (uuid)
typestring: member.created, member.updated, member.paused, member.resumed, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, payment_link.opened, promise.created, promise.kept, promise.broken, message.sent, message.received, message.classified
created_atstring (date-time)
dataobject

WebhookDelivery

CampoTipoObligatorioDescripción
idstring (uuid)
event_idstring (uuid)
event_typestring
endpoint_idstring (uuid)
statusstring: pending, delivered, failed
attemptsinteger
next_attempt_atstring (date-time), nullable
last_statusinteger, nullable
last_errorstring, nullable
created_atstring (date-time)
delivered_atstring (date-time), nullable

SequenceRun

CampoTipoObligatorioDescripción
idstring (uuid)
member_idstring (uuid)
billing_order_idstring (uuid), nullable
template_idstring (uuid)
statestring
channelstring
scheduled_atstring (date-time)
outcomestring, nullable
attemptsinteger

Flow

CampoTipoObligatorioDescripción
idstring (uuid)
namestring
statusstring
stepsinteger
typestring, nullable
anchorstring, nullable
audience_modestringmembers = explicit list (enroll/remove by API); otherwise all, active, states, tags, segments, auto_obligation.
rolestring: general, segment, suggestion, nullableCollection calendars only. general = the account's one general calendar (every client with an open charge not covered by a tag calendar); segment = applies to clients with its tags; suggestion = left by Makatea, never sends and cannot be activated until it is made the general calendar in the app. null for other flows.

FlowMembership

CampoTipoObligatorioDescripción
flow_idstring (uuid)
member_idstring (uuid)
enrolledboolean
changedbooleanfalse when it was already so.
flow_statusstring
runs_createdinteger
runs_withdrawninteger

PauseState

CampoTipoObligatorioDescripción
member_idstring (uuid)
pausedboolean
paused_untilstring (date-time), nullable
pause_reasonstring, nullable
paused_atstring (date-time), nullable
runs_rescheduledintegerOnly on resume.

Template

CampoTipoObligatorioDescripción
idstring (uuid)
namestring
channelstring
trigger_typestring
versioninteger
subjectstring, nullable

Stats

object

Loan

CampoTipoObligatorioDescripción
idstring (uuid)
member_idstring (uuid)
member_namestring, nullable
external_refstring, nullableYour folio.
principalnumberMoney lent.
total_amountnumber, nullable
periodsinteger, nullable
frequencystring, nullable
start_datestring (date)Date the money was lent.
statusstring: active, liquidated, cancelled
notesstring, nullable
scheduleobject, nullableHow Makatea generated its installments (null = attached by hand).
created_atstring (date-time)
updated_atstring (date-time)
totalsobject

SplitResult

CampoTipoObligatorioDescripción
parentBillingOrder
childrenarray de BillingOrder

LoanDetail

object

BatchResult

CampoTipoObligatorioDescripción
objectstring: batch
dry_runboolean
batch_idstring (uuid), nullableimport_batch_id stamped on the records (null for dry runs and payment batches).
summaryobject
resultsarray de object

AllocationRule

CampoTipoObligatorioDescripción
rulestring
rulesarray de string
orders_reappliedinteger