También en markdown y en OpenAPI.

Referencia de la API de Makatea

Generada del OpenAPI de producción (versión 2026-09-23). 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-API-Version: 2026-09-23 and an X-Request-Id (send your own to correlate logs).

Authentication

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

Authorization: Bearer mk_live_…
X-API-Key: mk_live_…

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": {…}}

with headers Makatea-Event-Id, Makatea-Event-Type 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, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, promise.created, promise.kept, promise.broken, message.sent, message.received. *.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). Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (unix seconds). Over the limit → 429 with Retry-After. Request bodies up to 21 MB; documents up to 15 MB.

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.
limitqueryinteger
cursorquerystringnext_cursor from the previous page.
offsetqueryintegerLegacy; prefer cursor.
countquerybooleanInclude pagination.total.

Respuestas

  • 200 OK · data: array de Member
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

POST /v1/members

Create a member.

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

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestringsí
phone_e164stringEjemplo: "+5215512345678".
emailstring
statestring: contact, active, at_risk, delinquent, dormant, churnedPor omisión: "active".
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
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

GET /v1/members/{id}

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

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: Member
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

PUT /v1/members/{id}

Update a member.

Only the fields you send are changed.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestring
phone_e164string
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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

PATCH /v1/members/{id}

Update a member (partial).

Only the fields you send are changed.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
full_namestring
phone_e164string
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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

DELETE /v1/members/{id}

Soft-delete a member (state becomes churned).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Member
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

Promises

GET /v1/members/{id}/promises

Current promise and history.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: PromiseState
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
promised_datestring (date)sí
amountnumber

Respuestas

  • 201 OK · data: PromiseState
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: PromiseState
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

Credit

GET /v1/members/{id}/credit

Credit balance and its ledger.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: Credit
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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

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

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: CreditApplied
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de Interaction
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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).

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
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

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.

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

Respuestas

  • 200 OK · data: ConversationImportResult
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de Document
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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

Delete a document (file and record).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí
document_idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Deleted
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de BillingOrder
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

POST /v1/billing-orders

Create a billing order.

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
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

GET /v1/billing-orders/{id}

Get a billing order.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: BillingOrder
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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).

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
reasonstring

Respuestas

  • 200 OK · data: BillingOrder
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
amountnumber
reasonstring

Respuestas

  • 200 OK · data: BillingOrder
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
amountnumbersí
collectibleboolean

Respuestas

  • 201 OK · data: BillingOrder
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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

Create (or reuse) a payment link with the organization's payment provider.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: PaymentLink
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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í

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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de Payment
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

GET /v1/payments/{id}

Get a payment.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: Payment
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
reasonstring

Respuestas

  • 200 OK · data: Payment
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de Loan
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

POST /v1/credits

Create a credit (loan) and attach its installments.

external_ref (your folio) is unique per organization: reusing it is 409. Installments are attached by id or by their external_ref; they must belong to the same member (422 credit_member_mismatch). start_date is when the money was lent: it decides in which period the principal counts as «placed».

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, monthly, daily, other
notesstring
billing_order_idsarray de string (uuid)
billing_order_external_refsarray de string

Respuestas

  • 201 OK · data: LoanDetail
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

GET /v1/credits/{id}

Get a credit with its installments and their breakdown.

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Respuestas

  • 200 OK · data: LoanDetail
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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í

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
external_refstring, nullable
principalnumber
start_datestring (date)
total_amountnumber, nullable
periodsinteger, nullable
frequencystring: weekly, biweekly, 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
  • 401 Missing or invalid credentials
  • 404 Not found
  • 422 Validation error
  • 429 Rate limit exceeded

GET /v1/settings/payment-allocation

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

Respuestas

  • 200 OK · data: AllocationRule
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

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).

Acepta Idempotency-Key.

Cuerpo (JSON)

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

Respuestas

  • 200 OK · data: AllocationRule
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

Webhooks

GET /v1/webhook-endpoints

List webhook endpoints.

Respuestas

  • 200 OK · data: array de WebhookEndpoint
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

POST /v1/webhook-endpoints

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

Acepta Idempotency-Key.

Cuerpo (JSON)

CampoTipoObligatorioDescripción
urlstring (uri)síhttps only; private/internal hosts are rejected.
eventsarray de string: *, member.created, member.updated, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, promise.created, promise.kept, promise.broken, message.sent, message.receivedsí
descriptionstring

Respuestas

  • 201 OK · data: WebhookEndpointCreated
  • 401 Missing or invalid credentials
  • 422 Validation error
  • 429 Rate limit exceeded

DELETE /v1/webhook-endpoints/{id}

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

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: Deleted
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de WebhookEvent
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de WebhookDelivery
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

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

Retry a delivery now (pending or failed).

Parámetros

NombreEnTipoObligatorioDescripción
idpathstring (uuid)sí

Acepta Idempotency-Key.

Respuestas

  • 200 OK · data: WebhookDelivery
  • 401 Missing or invalid credentials
  • 404 Not found
  • 429 Rate limit exceeded

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.

Respuestas

  • 200 OK · data: array de SequenceRun
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

GET /v1/flows

List the organization's flows.

Respuestas

  • 200 OK · data: array de Flow
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

GET /v1/templates

List the organization's active templates.

Respuestas

  • 200 OK · data: array de Template
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

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).

Respuestas

  • 200 OK · data: Stats
  • 401 Missing or invalid credentials
  • 429 Rate limit exceeded

Objetos

Error

CampoTipoObligatorioDescripción
errorobject

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
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
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)
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.

PaymentResult

CampoTipoObligatorioDescripción
order_idstring (uuid)
amount_paidnumber
statusstring
fully_paidboolean
excess_applied_to_other_ordersnumber
credit_addednumber
already_appliedboolean
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

object

WebhookEndpoint

CampoTipoObligatorioDescripción
idstring (uuid)
urlstring
eventsarray de string
activeboolean
descriptionstring, nullable
created_atstring (date-time)
updated_atstring (date-time)

WebhookEndpointCreated

object

WebhookEvent

CampoTipoObligatorioDescripción
idstring (uuid)
typestring: member.created, member.updated, billing_order.created, billing_order.updated, billing_order.paid, billing_order.cancelled, payment.received, payment.voided, promise.created, promise.kept, promise.broken, message.sent, message.received
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

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
created_atstring (date-time)
updated_atstring (date-time)
totalsobject

LoanDetail

object

AllocationRule

CampoTipoObligatorioDescripción
rulestring
rulesarray de string
orders_reappliedinteger