Skip to content

API reference

Staff console

72 operations, each with its parameters, curl and TypeScript examples ready to copy, and its errors.

These operations belong to Notificado's staff console: they answer authorised staff only and refuse every customer.

Every example assumes a signed-in session; how to get one is in Authentication

abuseOverview

GET/_x/query/abuse-overview

Notificado staff onlyPermission: admin:orgs:readMCP tool: abuseOverview

Staff only. Sending-abuse controls: every org's suspensions (active first; automatic = paused by complaint-watch pending review), org-specific sender limits (recipients per rolling hour/day), the per-plan defaults, and — with orgId — that org's active suspension, history, effective limit and usage in the last hour and 24 h. Org names and counts only.

Parameters of abuseOverview
NameInTypeRequired
orgIdQuerystring (uuid)No
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/abuse-overview' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/abuse-overview', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

adminAffiliates

GET/_x/query/admin-affiliates

Notificado staff onlyPermission: affiliate:admin

adminAffiliates

Parameters of adminAffiliates
NameInTypeRequired
limitQueryinteger 1–500No
statusQuery"applied" | "approved" | "suspended" | "closed"No
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/admin-affiliates' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/admin-affiliates', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

adminPayoutBatches

GET/_x/query/admin-payout-batches

Notificado staff onlyPermission: affiliate:adminMCP tool: adminPayoutBatches

Staff only (affiliate:admin). The affiliate payout batches, newest month first: period (YYYY-MM), status (draft → approved → executing → done), who built and who approved it, total net, and per payout the affiliate code, gross, withholding, ReteICA and net in COP minor units (centavos), status (draft, approved, sent, paid, failed, canceled), the transfer reference once paid, whether it awaits a manual bank transfer, and its DSNO number. No personal data.

Parameters of adminPayoutBatches
NameInTypeRequired
limitQueryinteger 1–60No
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/admin-payout-batches' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/admin-payout-batches', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

adminWithholdingRates

GET/_x/query/admin-withholding-rates

Notificado staff onlyPermission: affiliate:adminMCP tool: adminWithholdingRates

Staff only (affiliate:admin). The affiliate retención rate rows, newest first: concept, regime (non_declarant, declarant, art383, legal_entity), rateBps (null = the art. 383 ET table), reteIcaBps, validFrom/validTo (UTC), the norm cited, needsAccountantReview (true blocks every affiliate payout on that regime) and who reviewed it. No personal data.

Parameters of adminWithholdingRates
NameInTypeRequired
limitQueryinteger 1–200No
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/admin-withholding-rates' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/admin-withholding-rates', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

billingKpis

GET/_x/query/billing-kpis

Notificado staff onlyPermission: admin:kpi:readMCP tool: billingKpis

Staff only. Billing figures, no personal data, for payments created in [from, to): per payment method and status the count and the gross, net (after discount), discount and IVA sums in COP minor units (centavos); totals of payments ever approved; refunds recorded in the window; and the DIAN invoices and credit notes queued (pending manual issue) or rejected right now.

Parameters of billingKpis
NameInTypeRequired
fromQuerystring (date-time)Yes
toQuerystring (date-time)Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/billing-kpis?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/billing-kpis?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

catalogSnapshot

GET/_x/query/catalog-snapshot

Notificado staff onlyPermission: admin:config:readMCP tool: catalogSnapshot

Staff only. The sales catalog and provider configuration, read-only, no personal data: active credit packs (sends, price in COP minor units, validity days), plans with the prices in force per interval, coupons that still validate (with redeemed and reserved counts), and env flags — name, set, the non-secret value of each provider selector and what the app built from it (effective, or the X_* error code refusing it). Secrets are never listed; ADMIN_ALLOWED_IPS only says whether it is set.

Parameters of catalogSnapshot
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/catalog-snapshot' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/catalog-snapshot', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

deliverability

GET/_x/query/deliverability

Notificado staff onlyPermission: admin:orgs:readMCP tool: deliverability

Staff only. Email deliverability for events recorded in [from, to), no personal data: per America/Bogota day and per recipient domain (domains with fewer than 3 distinct addresses are grouped as "(other)") the sends, deliveries, hard and soft bounces, complaints and deferrals with rates in percent; the customer orgs with the most bounces (org id, name and counts only); and the SES account standing (production access, sending enabled, 24 h quota and usage). Window at most 92 days.

Parameters of deliverability
NameInTypeRequired
fromQuerystring (date-time)Yes
toQuerystring (date-time)Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/deliverability?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/deliverability?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

evidenceHealth

GET/_x/query/evidence-health

Notificado staff onlyPermission: admin:system:readMCP tool: evidenceHealth

Staff only. Evidence system health, no personal data: the last 14 daily anchors (Bogotá days; missing days listed; which timestamp authorities stamped each Merkle root), per-authority stamped/missed anchors plus tokens issued and stamp failures over the window, the last nightly evidence-chain verification verdict (ok, events checked, first broken seq), the latest NTP clock sample per host against the 100 ms threshold, and the mail transport account status (productionAccess false = SES sandbox: only verified recipients receive mail; 24 h quota and sent; errorCode when the provider could not be asked).

Parameters of evidenceHealth
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/evidence-health' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/evidence-health', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

funnelReport

GET/_x/query/funnel-report

Notificado staff onlyPermission: admin:kpi:readMCP tool: funnelReport

Staff only. The growth funnel for orgs that signed up in [from, to) (at most 190 days), no personal data: one row per signup week (Monday, America/Bogota) with counts of orgs that signed up, submitted KYC, were KYC-approved, started the trial, created a first case, sent a first notification, had a first delivery and paid; each stage's conversion from the previous one in percent; and trial-to-paid within 30 days in percent.

Parameters of funnelReport
NameInTypeRequired
fromQuerystring (date-time)Yes
toQuerystring (date-time)Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/funnel-report?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/funnel-report?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

jobQueues

GET/_x/query/job-queues

Notificado staff onlyPermission: admin:system:readMCP tool: jobQueues

Staff only. The background job queues, no personal data: per queue ready, delayed, running, suspended and dead counts plus oldestReadyMs; the last 50 dead letters (jobId, name, attempts, errorCode — never the input); every scheduled task with cron, time zone and nextRunAt (UTC); missing lists what this process cannot report (no driver, no introspection). Requeue a dead letter with requeueJob({ jobId }).

Parameters of jobQueues
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/job-queues' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/job-queues', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

kpiSnapshot

GET/_x/query/kpi-snapshot

Notificado staff onlyPermission: admin:kpi:readMCP tool: kpiSnapshot

Staff only. One America/Bogota month's launch KPIs (month as YYYY-MM), no personal data: signups; KYC submissions and the percent approved; trials started, the percent that sent a first notification (activation) and the percent that paid within 30 days (trial-to-paid); MRR in COP minor units (centavos, annual prices counted monthly) and live subscriptions at the month end; churn (subscriptions live at the month start that ended in it, percent); net revenue before IVA of payments approved in the month, the subscription part and its share. Revenue by payment method: billingKpis.

Parameters of kpiSnapshot
NameInTypeRequired
monthQuerystring 7–7Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/kpi-snapshot?month=<month>' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/kpi-snapshot?month=<month>', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

opsAlerts

GET/_x/query/ops-alerts

Notificado staff onlyPermission: admin:system:readMCP tool: opsAlerts

Staff only. The conditions operations must act on, most severe first: tsa_failures (timestamp authority failures in 24 h), anchor_missed (no daily Merkle anchor for the last due Bogotá day), clock_offset (NTP offset past 100 ms), chain_verify_failed and staff_audit_chain_broken (a nightly hash-chain verification failed), ses_sending_paused, ses_sandbox, ses_quota_high, bounce_rate_high (> 5 %) and complaint_rate_high (> 0.1 %) over 24 h. Each row: code, severity (info | warn | critical), since (UTC), href (console page), value (the figure). No personal data.

Parameters of opsAlerts
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/ops-alerts' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/ops-alerts', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

opsOverview

GET/_x/query/ops-overview

Notificado staff onlyPermission: admin:system:readMCP tool: opsOverview

Staff only. Operations counts, no personal data: lawyers pending KYC, four-eyes approvals pending, notifications and recipients created in the last 24 h by outcome (sent, failed, delivered, bounced, complained), and the job backlog.

Parameters of opsOverview
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/ops-overview' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/ops-overview', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

orphanApprovals

GET/_x/query/orphan-approvals

Notificado staff onlyPermission: admin:payments:readMCP tool: orphanApprovals

Staff only (admin:payments:read). Approvals the gateway reported for payments already closed without money (declined, voided, error) and not yet revived — the customer was charged and holds nothing. Per row: payment id, org id, reference, current status, the gateway event key (`transaction.updated:<txId>:APPROVED`), the gross in COP minor units (centavos) and when the approval was refused. Refund or void each at the gateway, or wait for the reconcile to revive it.

Parameters of orphanApprovals
NameInTypeRequired
limitQueryinteger 1–500No
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/orphan-approvals' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/orphan-approvals', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

pendingStaffConfirmations

GET/_x/query/pending-staff-confirmations

Notificado staff onlyPermission: admin:tokens:self

pendingStaffConfirmations

Parameters of pendingStaffConfirmations
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/pending-staff-confirmations' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/pending-staff-confirmations', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

previewPayoutBatch

GET/_x/query/preview-payout-batch

Notificado staff onlyPermission: affiliate:adminMCP tool: previewPayoutBatch

Staff only (affiliate:admin). Read-only preview of the affiliate payout batch for a closed month (period YYYY-MM): per affiliate whose payable balance reaches the $100,000 minimum, the code, gross, withholding (retención), ReteICA and net in COP minor units, the tax regime, and `held` — the reasons it would roll over instead (kyc_not_approved, terms_missing, payout_destination_missing, iva_responsible_invoice_required, payout_in_flight, below_minimum, refund_heavy, velocity, rate_missing, rate_unreviewed, art383_table_missing). Also the payable count, totals, and the regimes whose rate awaits accountant sign-off (which blocks building the batch). Writes nothing.

Parameters of previewPayoutBatch
NameInTypeRequired
periodQuerystring 7–7Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/preview-payout-batch?period=<period>' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/preview-payout-batch?period=<period>', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

providerHealth

GET/_x/query/provider-health

Notificado staff onlyPermission: admin:system:readMCP tool: providerHealth

Staff only. Liveness of every configured provider, no personal data: each timestamp authority, the PDF signer, the mail transport, the evidence and uploads storage disks, the payment gateway, the e-invoice provider and captcha — each { kind, id, ok, latencyMs, checkedAt, detail } where detail.code names why a provider is down. Probes are read-only (nothing is stamped, signed, sent or charged) and the answer is cached for 60 s.

Parameters of providerHealth
NameInTypeRequired
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/provider-health' \
  -b cookies.txt
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/provider-health', {
  headers: { cookie: sessionCookie },
});
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

viewAffiliateDocument

POST/api/affiliate-documents/view

Notificado staff onlyPermission: affiliate:admin

viewAffiliateDocument

Parameters of viewAffiliateDocument
NameInTypeRequired
affiliateIdBodystring (uuid)Yes
fileBody"rut" | "bank_cert"Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/affiliate-documents/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"affiliateId":"<affiliateId>","file":"rut","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/affiliate-documents/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "affiliateId": "<affiliateId>",
    "file": "rut",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "affiliateId": "<affiliateId>",
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "declarant": true,
  "declares383": true,
  "docNumber": "<docNumber>",
  "docType": "CC",
  "dv": "<dv>",
  "file": "rut",
  "filename": "<filename>",
  "intact": true,
  "ivaResponsible": true,
  "kycId": "<kycId>",
  "kycStatus": "pending",
  "legalEntity": true,
  "sha256": "<sha256>",
  "sha256Now": "<sha256Now>",
  "size": -9007199254740991,
  "submittedAt": "2026-09-25T15:00:00Z"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

reviewAffiliate

POST/api/affiliates/review

Notificado staff onlyPermission: affiliate:admin

reviewAffiliate

Parameters of reviewAffiliate
NameInTypeRequired
affiliateIdBodystring (uuid)Yes
decisionBody"approve" | "reject" | "suspend" | "reinstate"Yes
reasonBodystring 1–500No
curl
curl -X POST 'https://www.notificado.co/api/affiliates/review' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"affiliateId":"<affiliateId>","decision":"approve"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/affiliates/review', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "affiliateId": "<affiliateId>",
    "decision": "approve"
  }),
});
const result = await response.json();
Example response
200
{
  "affiliateId": "<affiliateId>",
  "kycStatus": "pending",
  "status": "applied"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

decideApproval

POST/api/approvals/decide

Notificado staff onlyPermission: admin:approvals:decide

decideApproval

Parameters of decideApproval
NameInTypeRequired
codeBodystring 1–64No
decisionBody"approve" | "reject"Yes
idBodystring (uuid)Yes
reasonBodystring 1–1000No
curl
curl -X POST 'https://www.notificado.co/api/approvals/decide' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"decision":"approve","id":"<id>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/approvals/decide', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "decision": "approve",
    "id": "<id>"
  }),
});
const result = await response.json();
Example response
200
{
  "amount": {
    "currency": "<currency>",
    "minor": -9007199254740991
  },
  "credits": -9007199254740991,
  "decidedAt": "2026-09-25T15:00:00Z",
  "decidedBy": "<decidedBy>",
  "decisionReason": "<decisionReason>",
  "executedRef": "<executedRef>",
  "expiresAt": "2026-09-25T15:00:00Z",
  "failureReason": "<failureReason>",
  "id": "<id>",
  "kind": "<kind>",
  "payload": {},
  "payloadSha256": "<payloadSha256>",
  "reason": "<reason>",
  "requestedAt": "2026-09-25T15:00:00Z",
  "requestedBy": "<requestedBy>",
  "status": "<status>",
  "subjectOrgId": "<subjectOrgId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listApprovals

POST/api/approvals/list

Notificado staff onlyPermission: admin:approvals:readMCP tool: listApprovals

Staff only. Four-eyes approval requests (credit grants/adjustments above 100 credits). Default: pending, oldest first; pass status for history (newest first). Every call is audited. A second staff member decides each with decideApproval in the console.

Parameters of listApprovals
NameInTypeRequired
cursorBodystring 1–200No
limitBodyinteger 1–200No
statusBody"pending" | "approved" | "rejected" | "executed" | "failed" | "expired"No
subjectOrgIdBodystring (uuid)No
curl
curl -X POST 'https://www.notificado.co/api/approvals/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/approvals/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "amount": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "credits": -9007199254740991,
      "decidedAt": "2026-09-25T15:00:00Z",
      "decidedBy": "<decidedBy>",
      "decisionReason": "<decisionReason>",
      "executedRef": "<executedRef>",
      "expiresAt": "2026-09-25T15:00:00Z",
      "failureReason": "<failureReason>",
      "id": "<id>",
      "kind": "<kind>",
      "payload": {},
      "payloadSha256": "<payloadSha256>",
      "reason": "<reason>",
      "requestedAt": "2026-09-25T15:00:00Z",
      "requestedBy": "<requestedBy>",
      "status": "<status>",
      "subjectOrgId": "<subjectOrgId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminArchiveCoupon

POST/api/archive-coupons/admin

Notificado staff onlyPermission: admin:coupons:writeMCP tool: adminArchiveCoupon

Staff only (admin:coupons:write). Archives a coupon by id (from adminListCoupons): new previews and checkouts refuse it; redemptions already made keep it. Idempotent. Recorded in the audit trail.

Parameters of adminArchiveCoupon
NameInTypeRequired
couponIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/archive-coupons/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"couponId":"<couponId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/archive-coupons/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "couponId": "<couponId>"
  }),
});
const result = await response.json();
Example response
200
{
  "affiliateId": "<affiliateId>",
  "amountOff": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  },
  "appliesTo": "pack",
  "archivedAt": "2026-09-25T15:00:00Z",
  "campaign": "<campaign>",
  "code": "<code>",
  "createdAt": "2026-09-25T15:00:00Z",
  "createdBy": "<createdBy>",
  "cycles": -9007199254740991,
  "duration": "once",
  "firstPurchaseOnly": true,
  "id": "<id>",
  "kind": "percent",
  "maxRedemptions": -9007199254740991,
  "percentBps": -9007199254740991,
  "validFrom": "2026-09-25T15:00:00Z",
  "validTo": "2026-09-25T15:00:00Z"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewAsOrg

POST/api/as-orgs/view

Notificado staff onlyPermission: admin:customer-data:readMCP tool: viewAsOrg

Staff only. A read-only snapshot of what one customer org's panel shows: the org, spendable credit balance and next expiry, KYC banner state, the 5 most recent notifications and cases. Read as a viewer of that org (no session, no writes possible). Needs a purpose (5+ characters). Every call is audited.

Parameters of viewAsOrg
NameInTypeRequired
orgIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/as-orgs/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/as-orgs/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "balance": -9007199254740991,
  "cases": [
    {
      "cliente": "<cliente>",
      "createdAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "juzgado": "<juzgado>",
      "radicado": "<radicado>"
    }
  ],
  "kycBanner": "<kycBanner>",
  "nextExpiry": {
    "at": "2026-09-25T15:00:00Z",
    "credits": -9007199254740991
  },
  "org": {
    "createdAt": "2026-09-25T15:00:00Z",
    "id": "<id>",
    "kind": "<kind>",
    "name": "<name>"
  },
  "recentNotifications": [
    {
      "caseId": "<caseId>",
      "createdAt": "<createdAt>",
      "id": "<id>",
      "sentAt": "<sentAt>",
      "status": "<status>",
      "subject": "<subject>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

exportAudit

POST/api/audits/export

Notificado staff onlyPermission: admin:audit:exportMCP tool: exportAudit

Staff only (superadmin, compliance). The staff-access audit trail for Bogotá days from..to (YYYY-MM-DD, both inclusive) as a CSV file: base64 bytes, filename and SHA-256. Oldest first; columns seq, at_utc, at_bogota, actor, action, outcome, subject, purpose, diff, prev_hash, hash. Optional filters actorId, subjectOrgId, subjectType/subjectId, outcome. At most 10000 rows — past that X_ADMIN_AUDIT_EXPORT_TOO_LARGE: split the range. This export is itself audited.

Parameters of exportAudit
NameInTypeRequired
actorIdBodystring 1–120No
fromBodystring 1–10Yes
outcomeBody"allowed" | "denied" | "failed"No
subjectIdBodystring 1–120No
subjectOrgIdBodystring (uuid)No
subjectTypeBodystring 1–64No
toBodystring 1–10Yes
curl
curl -X POST 'https://www.notificado.co/api/audits/export' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"from":"<from>","to":"<to>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/audits/export', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "from": "<from>",
    "to": "<to>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "filename": "<filename>",
  "rows": 0,
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listAudit

POST/api/audits/list

Notificado staff onlyPermission: admin:audit:readMCP tool: listAudit

Staff only (superadmin, compliance). The staff-access audit trail: every staff read of customer data and every refusal on a staff surface, newest first. Filter by actorId, subjectOrgId, subjectType/subjectId, outcome (allowed|denied|failed), from/to (UTC). Page with cursor. This read is itself audited.

Parameters of listAudit
NameInTypeRequired
actorIdBodystring 1–120No
cursorBodystring 1–24No
fromBodystring (date-time)No
limitBodyinteger 1–500No
outcomeBody"allowed" | "denied" | "failed"No
subjectIdBodystring 1–120No
subjectOrgIdBodystring (uuid)No
subjectTypeBodystring 1–64No
toBodystring (date-time)No
curl
curl -X POST 'https://www.notificado.co/api/audits/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/audits/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "action": "<action>",
      "actorId": "<actorId>",
      "actorRole": "<actorRole>",
      "at": "2026-09-25T15:00:00Z",
      "hash": "<hash>",
      "id": "<id>",
      "ip": "<ip>",
      "orgId": "<orgId>",
      "outcome": "<outcome>",
      "permission": "<permission>",
      "purpose": "<purpose>",
      "reason": "<reason>",
      "requestId": "<requestId>",
      "seq": "<seq>",
      "subjectId": "<subjectId>",
      "subjectOrgId": "<subjectOrgId>",
      "subjectType": "<subjectType>",
      "surface": "<surface>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminCreateCoupon

POST/api/create-coupons/admin

Notificado staff onlyPermission: admin:coupons:writeMCP tool: adminCreateCoupon

Staff only (admin:coupons:write). Creates a coupon: code (3–40 of A-Z 0-9 _ -, stored upper-case, never reused — X_PROMO_COUPON_CODE_TAKEN otherwise), kind percent (percentBps 1..10000) or fixed (amountOff in COP minor units, whole pesos), appliesTo pack | subscription | any, duration once | cycles (with cycles) | forever, optional firstPurchaseOnly, maxRedemptions across orgs, UTC validFrom/validTo and a campaign tag. The discount comes off the net before IVA. Recorded in the audit trail.

Parameters of adminCreateCoupon
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
amountOffBodyobjectinteger minor units plus an ISO 4217 currency codeNo
appliesToBody"pack" | "subscription" | "any"Yes
campaignBodystring 1–80No
codeBodystring 3–40Yes
cyclesBodyinteger 1–120No
durationBody"once" | "cycles" | "forever"Yes
firstPurchaseOnlyBodybooleanNo
kindBody"percent" | "fixed"Yes
maxRedemptionsBodyinteger 1–9007199254740991No
percentBpsBodyinteger 1–10000No
validFromBodystring (date-time)No
validToBodystring (date-time)No
curl
curl -X POST 'https://www.notificado.co/api/create-coupons/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"appliesTo":"pack","code":"<code>","duration":"once","kind":"percent"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/create-coupons/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "appliesTo": "pack",
    "code": "<code>",
    "duration": "once",
    "kind": "percent"
  }),
});
const result = await response.json();
Example response
200
{
  "affiliateId": "<affiliateId>",
  "amountOff": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  },
  "appliesTo": "pack",
  "archivedAt": "2026-09-25T15:00:00Z",
  "campaign": "<campaign>",
  "code": "<code>",
  "createdAt": "2026-09-25T15:00:00Z",
  "createdBy": "<createdBy>",
  "cycles": -9007199254740991,
  "duration": "once",
  "firstPurchaseOnly": true,
  "id": "<id>",
  "kind": "percent",
  "maxRedemptions": -9007199254740991,
  "percentBps": -9007199254740991,
  "validFrom": "2026-09-25T15:00:00Z",
  "validTo": "2026-09-25T15:00:00Z"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 409 X_IDEMPOTENCY_CONFLICT
  • 422 X_BODY_INVALID

viewCustomer360

POST/api/customer360s/view

Notificado staff onlyPermission: admin:orgs:readMCP tool: viewCustomer360

Staff only. The customer 360 of one org: members (email, role, second factor), lawyer KYC (cédula masked), credit balance and the last 20 ledger rows, notifications by status, subscription and plan, payments and DIAN invoices in summary, recipients sent in the last 30 days with bounce and complaint rates, active suspension and sender limit with usage, deadline (term) counts, affiliate attribution, and the newest staff support notes. Needs a purpose (5+ characters). Every call is audited.

Parameters of viewCustomer360
NameInTypeRequired
orgIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/customer360s/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/customer360s/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "attribution": {
    "boundAt": "2026-09-25T15:00:00Z",
    "kind": "<kind>",
    "via": "<via>",
    "voided": true,
    "windowEndsAt": "2026-09-25T15:00:00Z"
  },
  "balance": -9007199254740991,
  "deadlines": {
    "blockedByBounce": -9007199254740991,
    "endingThisWeek": -9007199254740991,
    "total": -9007199254740991
  },
  "delivery": {
    "bounceRate": 1,
    "bounced": -9007199254740991,
    "complained": -9007199254740991,
    "complaintRate": 1,
    "deferred": -9007199254740991,
    "delivered": -9007199254740991,
    "sent": -9007199254740991,
    "since": "2026-09-25T15:00:00Z"
  },
  "invoices": {
    "byStatus": {},
    "recent": [
      {
        "createdAt": "2026-09-25T15:00:00Z",
        "gross": {
          "currency": null,
          "minor": null
        },
        "invoiceId": "<invoiceId>",
        "issuedAt": "2026-09-25T15:00:00Z",
        "kind": "<kind>",
        "number": "<number>",
        "status": "<status>"
      }
    ]
  },
  "kycState": "<kycState>",
  "lawyers": [
    {
      "cedulaMasked": "<cedulaMasked>",
      "fullName": "<fullName>",
      "profileId": "<profileId>",
      "status": "<status>",
      "submittedAt": "2026-09-25T15:00:00Z",
      "userId": "<userId>",
      "vigenciaDocumentId": "<vigenciaDocumentId>"
    }
  ],
  "members": [
    {
      "email": "<email>",
      "joinedAt": "2026-09-25T15:00:00Z",
      "mfaEnrolled": true,
      "role": "<role>",
      "userId": "<userId>"
    }
  ],
  "notificationsByStatus": {},
  "org": {
    "createdAt": "2026-09-25T15:00:00Z",
    "id": "<id>",
    "kind": "<kind>",
    "name": "<name>"
  },
  "paymentSources": -9007199254740991,
  "payments": {
    "approvedGross": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "byStatus": {},
    "lastApprovedAt": "2026-09-25T15:00:00Z",
    "recent": [
      {
        "createdAt": "2026-09-25T15:00:00Z",
        "gross": {
          "currency": null,
          "minor": null
        },
        "method": "<method>",
        "paymentId": "<paymentId>",
        "purpose": "<purpose>",
        "reference": "<reference>",
        "status": "<status>"
      }
    ]
  },
  "pendingApprovals": -9007199254740991,
  "recentLedger": [
    {
      "createdAt": "2026-09-25T15:00:00Z",
      "createdBy": "<createdBy>",
      "delta": -9007199254740991,
      "expiresAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "invoiceRef": "<invoiceRef>",
      "kind": "<kind>",
      "packageId": "<packageId>",
      "recipientId": "<recipientId>"
    }
  ],
  "senderLimit": {
    "perDay": -9007199254740991,
    "perHour": -9007199254740991,
    "planCode": "<planCode>",
    "reason": "<reason>",
    "source": "<source>"
  },
  "subscription": {
    "cancelAtPeriodEnd": true,
    "collection": "<collection>",
    "currentPeriodEnd": "2026-09-25T15:00:00Z",
    "cycleGross": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "cycleStatus": "<cycleStatus>",
    "interval": "<interval>",
    "overageCount": -9007199254740991,
    "planCode": "<planCode>",
    "sends": -9007199254740991,
    "status": "<status>"
  },
  "supportNotes": {
    "recent": [
      {
        "authorId": "<authorId>",
        "authorRole": "<authorRole>",
        "body": "<body>",
        "createdAt": "2026-09-25T15:00:00Z",
        "id": "<id>",
        "orgId": "<orgId>"
      }
    ],
    "total": -9007199254740991
  },
  "suspension": {
    "automatic": true,
    "reason": "<reason>",
    "suspendedAt": "2026-09-25T15:00:00Z",
    "suspendedBy": "<suspendedBy>"
  },
  "usage": {
    "lastDay": -9007199254740991,
    "lastHour": -9007199254740991
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminDownloadAffiliateSupportDocument

POST/api/download-affiliate-support-documents/admin

Notificado staff onlyPermission: affiliate:admin

adminDownloadAffiliateSupportDocument

Parameters of adminDownloadAffiliateSupportDocument
NameInTypeRequired
formatBody"pdf" | "xml"No
payoutIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/download-affiliate-support-documents/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"payoutId":"<payoutId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/download-affiliate-support-documents/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "payoutId": "<payoutId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "filename": "<filename>",
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminDownloadGatewayEvent

POST/api/download-gateway-events/admin

Notificado staff onlyPermission: admin:payments:readMCP tool: adminDownloadGatewayEvent

Staff only (admin:payments:read). Returns the stored body of one payment gateway delivery (eventId from adminPaymentDetail) as base64 bytes with its SHA-256, size, verified flag and received-at. Read-only. Every call is recorded in the staff audit trail.

Parameters of adminDownloadGatewayEvent
NameInTypeRequired
eventIdBodystring (uuid)Yes
purposeBodystring 1–500No
curl
curl -X POST 'https://www.notificado.co/api/download-gateway-events/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"eventId":"<eventId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/download-gateway-events/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "eventId": "<eventId>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "eventId": "<eventId>",
  "filename": "<filename>",
  "rawIsReserialized": true,
  "receivedAt": "2026-09-25T15:00:00Z",
  "sha256": "<sha256>",
  "verified": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listDsrQueue

POST/api/dsr-queues/list

Notificado staff onlyPermission: admin:dsr:readMCP tool: listDsrQueue

Staff only (admin:dsr:read). The habeas-data (Ley 1581) request queue: open requests first, ordered by legal due date (dueAt, UTC; the extended date when the single extension was taken), with late=true when the due day in America/Bogota has passed. Each row: reference, kind (consulta | reclamo | actualizacion | supresion), whether the titular is a notification recipient or an account holder, identity and contact, message, outcome and response once answered, and the outcomes the respond form allows with and without evidence in scope. Evidence is never deleted: a supresión on evidence is answered with the retention basis. Every call is recorded in the staff audit trail.

Parameters of listDsrQueue
NameInTypeRequired
limitBodyinteger 1–200Yes
stateBody"open" | "closed" | "all"Yes
curl
curl -X POST 'https://www.notificado.co/api/dsr-queues/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"limit":1,"state":"open"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/dsr-queues/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "limit": 1,
    "state": "open"
  }),
});
const result = await response.json();
Example response
200
{
  "rows": [
    {
      "closedAt": "2026-09-25T15:00:00Z",
      "documentNumber": "<documentNumber>",
      "documentType": "<documentType>",
      "dueAt": "2026-09-25T15:00:00Z",
      "email": "<email>",
      "extended": true,
      "extensionReason": "<extensionReason>",
      "fullName": "<fullName>",
      "id": "<id>",
      "kind": "consulta",
      "late": true,
      "locale": "<locale>",
      "message": "<message>",
      "outcome": "answered",
      "outcomes": {
        "withEvidence": [
          null
        ],
        "withoutEvidence": [
          null
        ]
      },
      "phone": "<phone>",
      "receivedAt": "2026-09-25T15:00:00Z",
      "reference": "<reference>",
      "relatedTo": "<relatedTo>",
      "respondedAt": "2026-09-25T15:00:00Z",
      "responsableOrgId": "<responsableOrgId>",
      "responseMessage": "<responseMessage>",
      "retentionRule": true,
      "subject": "recipient",
      "touchesEvidence": true
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

extendDsr

POST/api/dsrs/extend

Notificado staff onlyPermission: admin:dsr:write

extendDsr

Parameters of extendDsr
NameInTypeRequired
idBodystring (uuid)Yes
reasonBodystring 10–1000Yes
curl
curl -X POST 'https://www.notificado.co/api/dsrs/extend' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"id":"<id>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/dsrs/extend', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "id": "<id>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "closedAt": "2026-09-25T15:00:00Z",
  "documentNumber": "<documentNumber>",
  "documentType": "<documentType>",
  "dueAt": "2026-09-25T15:00:00Z",
  "email": "<email>",
  "extended": true,
  "extensionReason": "<extensionReason>",
  "fullName": "<fullName>",
  "id": "<id>",
  "kind": "consulta",
  "late": true,
  "locale": "<locale>",
  "message": "<message>",
  "outcome": "answered",
  "outcomes": {
    "withEvidence": [
      "answered"
    ],
    "withoutEvidence": [
      "answered"
    ]
  },
  "phone": "<phone>",
  "receivedAt": "2026-09-25T15:00:00Z",
  "reference": "<reference>",
  "relatedTo": "<relatedTo>",
  "respondedAt": "2026-09-25T15:00:00Z",
  "responsableOrgId": "<responsableOrgId>",
  "responseMessage": "<responseMessage>",
  "retentionRule": true,
  "subject": "recipient",
  "touchesEvidence": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

respondDsr

POST/api/dsrs/respond

Notificado staff onlyPermission: admin:dsr:write

respondDsr

Parameters of respondDsr
NameInTypeRequired
idBodystring (uuid)Yes
messageBodystring 10–10000Yes
outcomeBody"answered" | "granted" | "partially_granted" | "retained_legal_basis" | "forwarded_to_responsable" | "incomplete" | "denied"Yes
responsableOrgIdBodystring (uuid)No
touchesEvidenceBody"yes" | "no"Yes
curl
curl -X POST 'https://www.notificado.co/api/dsrs/respond' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "id": "<id>",
  "message": "<message>",
  "outcome": "answered",
  "touchesEvidence": "yes"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/dsrs/respond', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "id": "<id>",
    "message": "<message>",
    "outcome": "answered",
    "touchesEvidence": "yes"
  }),
});
const result = await response.json();
Example response
200
{
  "closedAt": "2026-09-25T15:00:00Z",
  "documentNumber": "<documentNumber>",
  "documentType": "<documentType>",
  "dueAt": "2026-09-25T15:00:00Z",
  "email": "<email>",
  "extended": true,
  "extensionReason": "<extensionReason>",
  "fullName": "<fullName>",
  "id": "<id>",
  "kind": "consulta",
  "late": true,
  "locale": "<locale>",
  "message": "<message>",
  "outcome": "answered",
  "outcomes": {
    "withEvidence": [
      "answered"
    ],
    "withoutEvidence": [
      "answered"
    ]
  },
  "phone": "<phone>",
  "receivedAt": "2026-09-25T15:00:00Z",
  "reference": "<reference>",
  "relatedTo": "<relatedTo>",
  "respondedAt": "2026-09-25T15:00:00Z",
  "responsableOrgId": "<responsableOrgId>",
  "responseMessage": "<responseMessage>",
  "retentionRule": true,
  "subject": "recipient",
  "touchesEvidence": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminExportEvidenceZip

POST/api/export-evidence-zips/admin

Notificado staff onlyPermission: admin:evidence:exportMCP tool: adminExportEvidenceZip

Staff only. The offline-verifiable evidence zip of any org's notification, as base64 bytes with filename and SHA-256 (verified against the stored digest in this call); newest version unless version is given. Needs a purpose (5+ characters). Recorded on the staff trail, in the firm's audit log and as an evidence.viewed event. X_EVIDENCE_ZIP_NOT_READY while the zip is being built (it is queued) — ask again shortly.

Parameters of adminExportEvidenceZip
NameInTypeRequired
confirmTokenBodystring 1–200No
notificationIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
versionBodyinteger 1–9007199254740991No
curl
curl -X POST 'https://www.notificado.co/api/export-evidence-zips/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"notificationId":"<notificationId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/export-evidence-zips/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "notificationId": "<notificationId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "constanciaId": "<constanciaId>",
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "filename": "<filename>",
  "kind": "zip",
  "orgId": "<orgId>",
  "sha256": "<sha256>",
  "version": 1
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

postIncidentUpdate

POST/api/incident-updates/post

Notificado staff onlyPermission: admin:incident:writeMCP tool: postIncidentUpdate

Staff only (admin:incident:write). Posts a PUBLIC update (Spanish message, optional English messageEn) on an open incident of notificado.co/estado: status investigating | identified | monitoring, and optionally a new impact. Updates are never edited; to close the incident call resolveIncident. Recorded in the staff audit trail.

Parameters of postIncidentUpdate
NameInTypeRequired
idBodystring (uuid)Yes
impactBody"maintenance" | "degraded" | "partial_outage" | "major_outage" | ""No
messageBodystring 3–2000Yes
messageEnBodystring 0–2000No
statusBody"investigating" | "identified" | "monitoring"Yes
curl
curl -X POST 'https://www.notificado.co/api/incident-updates/post' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"id":"<id>","message":"<message>","status":"investigating"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/incident-updates/post', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "id": "<id>",
    "message": "<message>",
    "status": "investigating"
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "impact": "maintenance",
  "resolvedAt": "2026-09-25T15:00:00Z",
  "startedAt": "2026-09-25T15:00:00Z",
  "title": "<title>",
  "titleEn": "<titleEn>",
  "updates": [
    {
      "message": "<message>",
      "messageEn": "<messageEn>",
      "postedAt": "2026-09-25T15:00:00Z",
      "status": "investigating"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

createIncident

POST/api/incidents/create

Notificado staff onlyPermission: admin:incident:writeMCP tool: createIncident

Staff only (admin:incident:write). Opens an incident on the public status page notificado.co/estado with its first public update (status investigating). impact: maintenance | degraded | partial_outage | major_outage. title and message are Spanish and PUBLIC — no customer names or data; titleEn/messageEn are optional English courtesy lines. startedAt (UTC) defaults to now; only a maintenance may start in the future. Recorded in the staff audit trail.

Parameters of createIncident
NameInTypeRequired
impactBody"maintenance" | "degraded" | "partial_outage" | "major_outage"Yes
messageBodystring 3–2000Yes
messageEnBodystring 0–2000No
startedAtBodystring (date-time)No
titleBodystring 3–200Yes
titleEnBodystring 0–200No
curl
curl -X POST 'https://www.notificado.co/api/incidents/create' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"impact":"maintenance","message":"<message>","title":"<title>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/incidents/create', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "impact": "maintenance",
    "message": "<message>",
    "title": "<title>"
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "impact": "maintenance",
  "resolvedAt": "2026-09-25T15:00:00Z",
  "startedAt": "2026-09-25T15:00:00Z",
  "title": "<title>",
  "titleEn": "<titleEn>",
  "updates": [
    {
      "message": "<message>",
      "messageEn": "<messageEn>",
      "postedAt": "2026-09-25T15:00:00Z",
      "status": "investigating"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

resolveIncident

POST/api/incidents/resolve

Notificado staff onlyPermission: admin:incident:writeMCP tool: resolveIncident

Staff only (admin:incident:write). Resolves an open incident on notificado.co/estado with a closing PUBLIC update (Spanish message, optional English messageEn). A resolved incident cannot be reopened; a recurrence is a new incident (createIncident). Recorded in the staff audit trail.

Parameters of resolveIncident
NameInTypeRequired
idBodystring (uuid)Yes
messageBodystring 3–2000Yes
messageEnBodystring 0–2000No
curl
curl -X POST 'https://www.notificado.co/api/incidents/resolve' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"id":"<id>","message":"<message>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/incidents/resolve', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "id": "<id>",
    "message": "<message>"
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "impact": "maintenance",
  "resolvedAt": "2026-09-25T15:00:00Z",
  "startedAt": "2026-09-25T15:00:00Z",
  "title": "<title>",
  "titleEn": "<titleEn>",
  "updates": [
    {
      "message": "<message>",
      "messageEn": "<messageEn>",
      "postedAt": "2026-09-25T15:00:00Z",
      "status": "investigating"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

cancelJob

POST/api/jobs/cancel

Notificado staff onlyPermission: admin:jobs:write

cancelJob

Parameters of cancelJob
NameInTypeRequired
confirmBodystring 1–220Yes
jobIdBodystring 1–200Yes
reasonBodystring 1–500No
curl
curl -X POST 'https://www.notificado.co/api/jobs/cancel' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"confirm":"<confirm>","jobId":"<jobId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/jobs/cancel', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "confirm": "<confirm>",
    "jobId": "<jobId>"
  }),
});
const result = await response.json();
Example response
200
{
  "attempt": -9007199254740991,
  "id": "<id>",
  "maxAttempts": -9007199254740991,
  "name": "<name>",
  "queue": "<queue>",
  "runAt": "2026-09-25T15:00:00Z",
  "state": "<state>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requeueJob

POST/api/jobs/requeue

Notificado staff onlyPermission: admin:jobs:writeMCP tool: requeueJob

Staff only (ops, superadmin). Requeue one finished job — dead, cancelled or done — by jobId (from jobQueues), optionally fromStep. A running or waiting job is refused. Through MCP the call waits for your human to confirm it in /admin/mcp. Audited.

Parameters of requeueJob
NameInTypeRequired
fromStepBodystring 1–200No
jobIdBodystring 1–200Yes
curl
curl -X POST 'https://www.notificado.co/api/jobs/requeue' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"jobId":"<jobId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/jobs/requeue', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "jobId": "<jobId>"
  }),
});
const result = await response.json();
Example response
200
{
  "attempt": -9007199254740991,
  "id": "<id>",
  "maxAttempts": -9007199254740991,
  "name": "<name>",
  "queue": "<queue>",
  "runAt": "2026-09-25T15:00:00Z",
  "state": "<state>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewKycDocument

POST/api/kyc-documents/view

Notificado staff onlyPermission: kyc:review

viewKycDocument

Parameters of viewKycDocument
NameInTypeRequired
profileIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/kyc-documents/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"profileId":"<profileId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/kyc-documents/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "profileId": "<profileId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "documentId": "<documentId>",
  "filename": "<filename>",
  "intact": true,
  "orgId": "<orgId>",
  "profileId": "<profileId>",
  "sha256": "<sha256>",
  "sha256Now": "<sha256Now>",
  "size": -9007199254740991
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listKycQueue

POST/api/kyc-queues/list

Notificado staff onlyPermission: kyc:reviewMCP tool: listKycQueue

Staff only. The lawyers waiting for KYC review across every firm, oldest first: name, cédula, tarjeta profesional, SIRNA email, the firm name, and the uploaded certificado de vigencia (id, SHA-256, type). Every call is audited. Decide each with approveKyc or rejectKyc.

Parameters of listKycQueue
NameInTypeRequired
limitBodyinteger 1–200No
curl
curl -X POST 'https://www.notificado.co/api/kyc-queues/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/kyc-queues/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
[
  {
    "cedula": "<cedula>",
    "fullName": "<fullName>",
    "orgId": "<orgId>",
    "orgName": "<orgName>",
    "profileId": "<profileId>",
    "sirnaEmail": "<sirnaEmail>",
    "submittedAt": "2026-09-25T15:00:00Z",
    "tarjetaProfesional": "<tarjetaProfesional>",
    "userId": "<userId>",
    "vigenciaDocumentId": "<vigenciaDocumentId>",
    "vigenciaDocumentSha256": "<vigenciaDocumentSha256>",
    "vigenciaDocumentType": "<vigenciaDocumentType>",
    "warnings": [
      "<warnings>"
    ]
  }
]

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

approveKyc

POST/api/kycs/approve

Notificado staff onlyPermission: kyc:reviewMCP tool: approveKyc

Staff only. Approve a pending lawyer KYC after checking the certificado de vigencia against the CSJ: records the decision with its reason, grants the firm its one-time trial credits and mails the lawyer. Pass orgId and profileId exactly as listKycQueue returned them.

Parameters of approveKyc
NameInTypeRequired
documentIdBodystring (uuid)No
orgIdBodystring (uuid)Yes
profileIdBodystring (uuid)Yes
reasonBodystring 1–2000Yes
curl
curl -X POST 'https://www.notificado.co/api/kycs/approve' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","profileId":"<profileId>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/kycs/approve', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "profileId": "<profileId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "checkId": "<checkId>",
  "profileId": "<profileId>",
  "status": "<status>",
  "trial": {
    "credits": -9007199254740991,
    "expiresAt": "2026-09-25T15:00:00Z"
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

rejectKyc

POST/api/kycs/reject

Notificado staff onlyPermission: kyc:reviewMCP tool: rejectKyc

Staff only. Reject a pending lawyer KYC (for example an expired or unreadable certificado de vigencia). The reason is mailed to the lawyer verbatim, so write it for them. Pass orgId and profileId exactly as listKycQueue returned them.

Parameters of rejectKyc
NameInTypeRequired
documentIdBodystring (uuid)No
orgIdBodystring (uuid)Yes
profileIdBodystring (uuid)Yes
reasonBodystring 1–2000Yes
curl
curl -X POST 'https://www.notificado.co/api/kycs/reject' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","profileId":"<profileId>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/kycs/reject', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "profileId": "<profileId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "checkId": "<checkId>",
  "profileId": "<profileId>",
  "status": "<status>",
  "trial": {
    "credits": -9007199254740991,
    "expiresAt": "2026-09-25T15:00:00Z"
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

staffLedgerList

POST/api/ledger-lists/staff

Notificado staff onlyPermission: admin:orgs:readMCP tool: staffLedgerList

Staff only. One customer org's credit ledger (grants, trial, consumption, refunds, adjustments, expiries), newest first; page with cursor. Every call is audited.

Parameters of staffLedgerList
NameInTypeRequired
cursorBodystring 1–200No
limitBodyinteger 1–200No
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/ledger-lists/staff' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/ledger-lists/staff', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "createdAt": "2026-09-25T15:00:00Z",
      "createdBy": "<createdBy>",
      "delta": -9007199254740991,
      "expiresAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "invoiceRef": "<invoiceRef>",
      "kind": "<kind>",
      "packageId": "<packageId>",
      "recipientId": "<recipientId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminListCoupons

POST/api/list-coupons/admin

Notificado staff onlyPermission: admin:coupons:readMCP tool: adminListCoupons

Staff only (admin:coupons:read). Lists coupons newest first: code, percent (basis points) or fixed amount (COP minor units), what it applies to (pack | subscription | any), duration (once | cycles | forever), first-purchase-only, max redemptions, UTC validity window, campaign tag, archived instant, and live redemption counts (reserved by open checkouts, committed by approved payments). Archived coupons only with includeArchived: true; filter by campaign.

Parameters of adminListCoupons
NameInTypeRequired
campaignBodystring 1–80No
includeArchivedBodybooleanNo
limitBodyinteger 1–500No
curl
curl -X POST 'https://www.notificado.co/api/list-coupons/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/list-coupons/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "rows": [
    {
      "committed": -9007199254740991,
      "coupon": {
        "affiliateId": "<affiliateId>",
        "amountOff": {
          "currency": null,
          "minor": null,
          "scale": null
        },
        "appliesTo": "pack",
        "archivedAt": "2026-09-25T15:00:00Z",
        "campaign": "<campaign>",
        "code": "<code>",
        "createdAt": "2026-09-25T15:00:00Z",
        "createdBy": "<createdBy>",
        "cycles": -9007199254740991,
        "duration": "once",
        "firstPurchaseOnly": true,
        "id": "<id>",
        "kind": "percent",
        "maxRedemptions": -9007199254740991,
        "percentBps": -9007199254740991,
        "validFrom": "2026-09-25T15:00:00Z",
        "validTo": "2026-09-25T15:00:00Z"
      },
      "reserved": -9007199254740991
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminListPayments

POST/api/list-payments/admin

Notificado staff onlyPermission: admin:payments:readMCP tool: adminListPayments

Staff only (admin:payments:read). Lists payments across every customer org, newest first: org, gateway reference, status, method, gross in COP minor units (centavos), created/approved instants and the DIAN invoice status. Filter by status, orgId, a createdAt window (from inclusive, to exclusive) and q (reference prefix, Wompi transaction id, payment id prefix or part of the org name); page with cursor. Every call is recorded in the staff audit trail.

Parameters of adminListPayments
NameInTypeRequired
cursorBodystring 1–200No
fromBodystring (date-time)No
limitBodyinteger 1–200Yes
orgIdBodystring (uuid)No
qBodystring 1–120No
statusBody"created" | "pending" | "approved" | "declined" | "voided" | "error" | "refunded" | "partially_refunded"No
toBodystring (date-time)No
curl
curl -X POST 'https://www.notificado.co/api/list-payments/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"limit":1}'
TypeScript
const response = await fetch('https://www.notificado.co/api/list-payments/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "limit": 1
  }),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "approvedAt": "2026-09-25T15:00:00Z",
      "createdAt": "2026-09-25T15:00:00Z",
      "gross": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "invoiceStatus": "<invoiceStatus>",
      "method": "<method>",
      "orgId": "<orgId>",
      "orgName": "<orgName>",
      "paymentId": "<paymentId>",
      "reference": "<reference>",
      "status": "created"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requestManualInvoiceUpload

POST/api/manual-invoice-uploads/request

Notificado staff onlyPermission: admin:invoicing:issueMCP tool: requestManualInvoiceUpload

Staff only (admin:invoicing:issue). Step 1 of recording an invoice issued by hand in DIAN software: returns a signed PUT url for its PDF (application/pdf, at most 5 MB). PUT the bytes there, then call recordManualInvoice with the returned key as pdfKey.

Parameters of requestManualInvoiceUpload
NameInTypeRequired
filenameBodystring 1–255Yes
sizeBodyinteger 0–9007199254740991No
curl
curl -X POST 'https://www.notificado.co/api/manual-invoice-uploads/request' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"filename":"<filename>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/manual-invoice-uploads/request', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "filename": "<filename>"
  }),
});
const result = await response.json();
Example response
200
{
  "contentType": "<contentType>",
  "expiresAt": -9007199254740991,
  "key": "<key>",
  "maxBytes": -9007199254740991,
  "method": "PUT",
  "url": "<url>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

pendingManualInvoices

POST/api/manual-invoices/pending

Notificado staff onlyPermission: admin:invoicing:issueMCP tool: pendingManualInvoices

Staff only (admin:invoicing:issue). The queued DIAN invoices and credit notes (document: invoice | credit_note; a credit note names the invoice it corrects) waiting to be issued by hand (EINVOICE_PROVIDER=manual), oldest first, each with buyer, lines, amounts in COP minor units (centavos), form of payment and our reference. Issue each in the DIAN software, then record it with recordManualInvoice. Every call is recorded in the staff audit trail.

Parameters of pendingManualInvoices
NameInTypeRequired
limitBodyinteger 1–500No
curl
curl -X POST 'https://www.notificado.co/api/manual-invoices/pending' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/manual-invoices/pending', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "rows": [
    {
      "amountGross": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "amountIva": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "amountNet": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "buyer": {
        "address": "<address>",
        "checkDigit": "<checkDigit>",
        "email": "<email>",
        "legalId": "<legalId>",
        "legalIdType": "<legalIdType>",
        "municipalityCode": "<municipalityCode>",
        "name": "<name>",
        "personType": "<personType>"
      },
      "corrects": {
        "cufe": "<cufe>",
        "id": "<id>",
        "number": "<number>"
      },
      "createdAt": "2026-09-25T15:00:00Z",
      "discount": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "document": "invoice",
      "dueAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "kind": "<kind>",
      "lines": [
        {
          "description": null,
          "discount": null,
          "ivaRate": null,
          "quantity": null,
          "unitNet": null
        }
      ],
      "orgId": "<orgId>",
      "paymentForm": "<paymentForm>",
      "paymentId": "<paymentId>",
      "reference": "<reference>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

recordManualInvoice

POST/api/manual-invoices/record

Notificado staff onlyPermission: admin:invoicing:issueMCP tool: recordManualInvoice

Staff only (admin:invoicing:issue). Records a DIAN invoice or credit note issued by hand in external DIAN software for a queued document (see pendingManualInvoices): its DIAN number, CUFE/CUDE (96 hex chars), issue time, and the PDF uploaded via requestManualInvoiceUpload (pdfKey). Marks it issued exactly once; the customer can then download it.

Parameters of recordManualInvoice
NameInTypeRequired
codeBodystringYes
documentBody"invoice" | "credit_note"Yes
idBodystring (uuid)Yes
issuedAtBodystring (date-time)Yes
numberBodystringYes
orgIdBodystring (uuid)Yes
pdfKeyBodystring 1–512Yes
curl
curl -X POST 'https://www.notificado.co/api/manual-invoices/record' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "code": "<code>",
  "document": "invoice",
  "id": "<id>",
  "issuedAt": "2026-09-25T15:00:00Z",
  "number": "<number>",
  "orgId": "<orgId>",
  "pdfKey": "<pdfKey>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/manual-invoices/record', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "code": "<code>",
    "document": "invoice",
    "id": "<id>",
    "issuedAt": "2026-09-25T15:00:00Z",
    "number": "<number>",
    "orgId": "<orgId>",
    "pdfKey": "<pdfKey>"
  }),
});
const result = await response.json();
Example response
200
{
  "code": "<code>",
  "document": "invoice",
  "id": "<id>",
  "issuedAt": "2026-09-25T15:00:00Z",
  "number": "<number>",
  "pdfSha256": "<pdfSha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

recordManualPayout

POST/api/manual-payouts/record

Notificado staff onlyPermission: affiliate:admin

recordManualPayout

Parameters of recordManualPayout
NameInTypeRequired
noteBodystring 1–500No
outcomeBody"paid" | "failed"Yes
payoutIdBodystring (uuid)Yes
referenceBodystring 1–64No
curl
curl -X POST 'https://www.notificado.co/api/manual-payouts/record' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"outcome":"paid","payoutId":"<payoutId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/manual-payouts/record', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "outcome": "paid",
    "payoutId": "<payoutId>"
  }),
});
const result = await response.json();
Example response
200
{
  "payoutId": "<payoutId>",
  "reference": "<reference>",
  "status": "<status>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

searchNotifications

POST/api/notifications/search

Notificado staff onlyPermission: admin:customer-data:readMCP tool: searchNotifications

Staff only. Finds notifications of any customer org by 23-digit radicado, recipient email (or part of it), SES MessageId, notification or recipient id, or constancia verify code; newest first, with org, case radicado, status, sentAt, recipient count and each live recipient (recipientId, email, status; the matched one first). At least 3 characters. Every call is audited with its term.

Parameters of searchNotifications
NameInTypeRequired
cursorBodystring 1–200No
limitBodyinteger 1–100No
termBodystring 1–320Yes
curl
curl -X POST 'https://www.notificado.co/api/notifications/search' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"term":"<term>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/notifications/search', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "term": "<term>"
  }),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "caseRadicado": "<caseRadicado>",
      "createdAt": "2026-09-25T15:00:00Z",
      "notificationId": "<notificationId>",
      "orgId": "<orgId>",
      "orgName": "<orgName>",
      "recipientCount": -9007199254740991,
      "recipients": [
        {
          "email": null,
          "recipientId": null,
          "status": null
        }
      ],
      "sentAt": "2026-09-25T15:00:00Z",
      "status": "<status>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

searchOrgs

POST/api/orgs/search

Notificado staff onlyPermission: admin:orgs:readMCP tool: searchOrgs

Staff only. Finds customer orgs by part of the name, a member email, an org id prefix (4+ hex chars) or a 23-digit radicado; newest first, with member count, KYC state and credit balance. At least 3 characters. Every call is audited with its term.

Parameters of searchOrgs
NameInTypeRequired
cursorBodystring 1–200No
limitBodyinteger 1–100No
termBodystring 1–200Yes
curl
curl -X POST 'https://www.notificado.co/api/orgs/search' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"term":"<term>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/orgs/search', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "term": "<term>"
  }),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "balance": -9007199254740991,
      "createdAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "kind": "<kind>",
      "kycState": "<kycState>",
      "memberCount": -9007199254740991,
      "name": "<name>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

suspendOrg

POST/api/orgs/suspend

Notificado staff onlyPermission: abuse:write

suspendOrg

Parameters of suspendOrg
NameInTypeRequired
orgIdBodystring (uuid)Yes
reasonBodystring 3–1000Yes
curl
curl -X POST 'https://www.notificado.co/api/orgs/suspend' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/orgs/suspend', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "liftedAt": "2026-09-25T15:00:00Z",
  "liftedBy": "<liftedBy>",
  "orgId": "<orgId>",
  "reason": "<reason>",
  "suspendedAt": "2026-09-25T15:00:00Z",
  "suspendedBy": "<suspendedBy>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewOrg

POST/api/orgs/view

Notificado staff onlyPermission: admin:orgs:readMCP tool: viewOrg

Staff only. One customer org: members (email, role, MFA), lawyer KYC status (cédula masked), credit balance with the last 20 ledger rows, notification counts by status, pending approvals. Every call is audited.

Parameters of viewOrg
NameInTypeRequired
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/orgs/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/orgs/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "balance": -9007199254740991,
  "kycState": "<kycState>",
  "lawyers": [
    {
      "cedulaMasked": "<cedulaMasked>",
      "fullName": "<fullName>",
      "profileId": "<profileId>",
      "status": "<status>",
      "submittedAt": "2026-09-25T15:00:00Z",
      "userId": "<userId>",
      "vigenciaDocumentId": "<vigenciaDocumentId>"
    }
  ],
  "members": [
    {
      "email": "<email>",
      "joinedAt": "2026-09-25T15:00:00Z",
      "mfaEnrolled": true,
      "role": "<role>",
      "userId": "<userId>"
    }
  ],
  "notificationsByStatus": {},
  "org": {
    "createdAt": "2026-09-25T15:00:00Z",
    "id": "<id>",
    "kind": "<kind>",
    "name": "<name>"
  },
  "pendingApprovals": -9007199254740991,
  "recentLedger": [
    {
      "createdAt": "2026-09-25T15:00:00Z",
      "createdBy": "<createdBy>",
      "delta": -9007199254740991,
      "expiresAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "invoiceRef": "<invoiceRef>",
      "kind": "<kind>",
      "packageId": "<packageId>",
      "recipientId": "<recipientId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminPaymentDetail

POST/api/payment-details/admin

Notificado staff onlyPermission: admin:payments:readMCP tool: adminPaymentDetail

Staff only (admin:payments:read). One payment by paymentId, in any org: amounts (COP minor units), status history markers, the gateway events about it (verified or not, applied or with the apply error, SHA-256 and size of the stored raw body), the credit ledger rows it produced, its DIAN invoice and credit notes, refunds and refund approval requests, and the amount still refundable. Every call is recorded in the staff audit trail.

Parameters of adminPaymentDetail
NameInTypeRequired
paymentIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/payment-details/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"paymentId":"<paymentId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/payment-details/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "paymentId": "<paymentId>"
  }),
});
const result = await response.json();
Example response
200
{
  "creditNotes": [
    {
      "amountGross": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "cude": "<cude>",
      "id": "<id>",
      "issuedAt": "2026-09-25T15:00:00Z",
      "number": "<number>",
      "refundId": "<refundId>",
      "status": "<status>",
      "statusAt": "2026-09-25T15:00:00Z"
    }
  ],
  "events": [
    {
      "appliedAt": "2026-09-25T15:00:00Z",
      "applyError": "<applyError>",
      "eventId": "<eventId>",
      "eventKey": "<eventKey>",
      "eventType": "<eventType>",
      "provider": "<provider>",
      "rawBytes": -9007199254740991,
      "rawIsReserialized": true,
      "rawSha256": "<rawSha256>",
      "receivedAt": "2026-09-25T15:00:00Z",
      "verified": true
    }
  ],
  "invoice": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "cufe": "<cufe>",
    "id": "<id>",
    "issuedAt": "2026-09-25T15:00:00Z",
    "kind": "<kind>",
    "number": "<number>",
    "status": "<status>",
    "statusAt": "2026-09-25T15:00:00Z"
  },
  "ledger": [
    {
      "createdAt": "2026-09-25T15:00:00Z",
      "createdBy": "<createdBy>",
      "delta": -9007199254740991,
      "expiresAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "kind": "<kind>",
      "source": "<source>",
      "sourceId": "<sourceId>"
    }
  ],
  "payment": {
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "attempt": -9007199254740991,
    "couponId": "<couponId>",
    "createdAt": "2026-09-25T15:00:00Z",
    "createdBy": "<createdBy>",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "gatewayTxId": "<gatewayTxId>",
    "gross": {
      "currency": "<currency>",
      "minor": -9007199254740991
    },
    "method": "<method>",
    "orgId": "<orgId>",
    "orgName": "<orgName>",
    "packCode": "<packCode>",
    "packSends": -9007199254740991,
    "paymentId": "<paymentId>",
    "purpose": "<purpose>",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  },
  "refundRequests": [
    {
      "amount": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "approvalRequestId": "<approvalRequestId>",
      "decidedBy": "<decidedBy>",
      "failureReason": "<failureReason>",
      "reason": "<reason>",
      "requestedAt": "2026-09-25T15:00:00Z",
      "requestedBy": "<requestedBy>",
      "status": "<status>"
    }
  ],
  "refundable": {
    "currency": "<currency>",
    "minor": -9007199254740991
  },
  "refunded": {
    "currency": "<currency>",
    "minor": -9007199254740991
  },
  "refunds": [
    {
      "amountGross": {
        "currency": "<currency>",
        "minor": -9007199254740991
      },
      "approvalRequestId": "<approvalRequestId>",
      "createdAt": "2026-09-25T15:00:00Z",
      "createdBy": "<createdBy>",
      "creditsReversed": -9007199254740991,
      "id": "<id>",
      "reason": "<reason>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

createPayoutBatch

POST/api/payout-batches/create

Notificado staff onlyPermission: affiliate:admin

createPayoutBatch

Parameters of createPayoutBatch
NameInTypeRequired
periodBodystring 7–7Yes
curl
curl -X POST 'https://www.notificado.co/api/payout-batches/create' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"period":"<period>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/payout-batches/create', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "period": "<period>"
  }),
});
const result = await response.json();
Example response
200
{
  "approvalRequestId": "<approvalRequestId>",
  "batchId": "<batchId>",
  "held": -9007199254740991,
  "payouts": -9007199254740991,
  "period": "<period>",
  "status": "<status>",
  "totalNet": {
    "currency": "<currency>",
    "minor": -9007199254740991
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewRawEvent

POST/api/raw-events/view

Notificado staff onlyPermission: admin:customer-data:readMCP tool: viewRawEvent

Staff only. The raw provider payload behind one evidence event (SES/SNS JSON, inbound reply notification, transport receipt), base64, exactly as stored, with its SHA-256 recomputed now and compared with the digest the hash-chained event committed to (match). Needs a purpose (5+ characters). Read-only; every call is audited.

Parameters of viewRawEvent
NameInTypeRequired
eventIdBodystring (uuid)Yes
purposeBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/raw-events/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"eventId":"<eventId>","purpose":"<purpose>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/raw-events/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "eventId": "<eventId>",
    "purpose": "<purpose>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": -9007199254740991,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "eventId": "<eventId>",
  "filename": "<filename>",
  "match": true,
  "orgId": "<orgId>",
  "recomputedSha256": "<recomputedSha256>",
  "storedSha256": "<storedSha256>",
  "type": "<type>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewRecipientTimeline

POST/api/recipient-timelines/view

Notificado staff onlyPermission: admin:customer-data:readMCP tool: viewRecipientTimeline

Staff only. One recipient of a notification as the evidence shows it: recipient and notification (org, case radicado, frozen .eml SHA-256), address provenance and sworn statement, attachment SHA-256s, every evidence event in chain order (UTC and Bogotá time, seq, hash, prevHash, indicio flag for opens, hasRaw) and the constancia versions. Read-only. Every call is audited.

Parameters of viewRecipientTimeline
NameInTypeRequired
purposeBodystring 1–500No
recipientIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/recipient-timelines/view' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"recipientId":"<recipientId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/recipient-timelines/view', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "recipientId": "<recipientId>"
  }),
});
const result = await response.json();
Example response
200
{
  "attachments": [
    {
      "bytes": -9007199254740991,
      "kind": "<kind>",
      "name": "<name>",
      "sha256": "<sha256>"
    }
  ],
  "constancias": [
    {
      "issuedAt": "2026-09-25T15:00:00Z",
      "sha256": "<sha256>",
      "verifyCode": "<verifyCode>",
      "version": -9007199254740991
    }
  ],
  "events": [
    {
      "eventId": "<eventId>",
      "hasRaw": true,
      "hash": "<hash>",
      "indicio": true,
      "occurredAt": "2026-09-25T15:00:00Z",
      "occurredAtBogota": "<occurredAtBogota>",
      "payloadJson": "<payloadJson>",
      "prevHash": "<prevHash>",
      "recipientId": "<recipientId>",
      "recordedAt": "2026-09-25T15:00:00Z",
      "seq": -9007199254740991,
      "type": "<type>"
    }
  ],
  "notification": {
    "caseId": "<caseId>",
    "caseRadicado": "<caseRadicado>",
    "createdAt": "2026-09-25T15:00:00Z",
    "emlSha256": "<emlSha256>",
    "frozenAt": "2026-09-25T15:00:00Z",
    "id": "<id>",
    "orgId": "<orgId>",
    "orgName": "<orgName>",
    "sentAt": "2026-09-25T15:00:00Z",
    "status": "<status>",
    "subject": "<subject>"
  },
  "provenance": {
    "evidenceDocumentIds": [
      "<evidenceDocumentIds>"
    ],
    "juramentoVersion": "<juramentoVersion>",
    "overrideReason": "<overrideReason>",
    "source": "<source>",
    "sourceText": "<sourceText>",
    "swornAt": "2026-09-25T15:00:00Z",
    "swornBy": "<swornBy>"
  },
  "recipient": {
    "createdAt": "2026-09-25T15:00:00Z",
    "email": "<email>",
    "headerMessageId": "<headerMessageId>",
    "id": "<id>",
    "messageId": "<messageId>",
    "name": "<name>",
    "status": "<status>"
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminReconcilePayment

POST/api/reconcile-payments/admin

Notificado staff onlyPermission: admin:payments:readMCP tool: adminReconcilePayment

Staff only (admin:payments:read). Enqueues a reconciliation of one payment now: the server asks the payment gateway for its transaction and applies the answer (idempotent — an approved payment stays approved; missing credits or invoice are repaired). Returns the status before it runs; read adminPaymentDetail again after a few seconds. Recorded in the staff audit trail.

Parameters of adminReconcilePayment
NameInTypeRequired
paymentIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/reconcile-payments/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"paymentId":"<paymentId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/reconcile-payments/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "paymentId": "<paymentId>"
  }),
});
const result = await response.json();
Example response
200
{
  "enqueued": true,
  "orgId": "<orgId>",
  "paymentId": "<paymentId>",
  "status": "created"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminReissueConstancia

POST/api/reissue-constancias/admin

Notificado staff onlyPermission: admin:evidence:reissueMCP tool: adminReissueConstancia

Staff only. Queue the next version of a notification's constancia (signed PDF built from every evidence event so far); earlier versions are never overwritten and keep verifying as superseded. Needs a reason (5+ characters). Fails X_CONSTANCIA_NOT_FOUND before the first constancia exists. Audited, and recorded in the firm's own audit log.

Parameters of adminReissueConstancia
NameInTypeRequired
confirmTokenBodystring 1–200No
notificationIdBodystring (uuid)Yes
reasonBodystring 1–1000Yes
curl
curl -X POST 'https://www.notificado.co/api/reissue-constancias/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"notificationId":"<notificationId>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/reissue-constancias/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "notificationId": "<notificationId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "notificationId": "<notificationId>",
  "orgId": "<orgId>",
  "queued": true,
  "version": 2
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminRequestRefund

POST/api/request-refunds/admin

Notificado staff onlyPermission: admin:payments:refundMCP tool: adminRequestRefund

Staff only (admin:payments:refund). Files a four-eyes refund request for one approved payment: gross in COP minor units (at most the refundable amount adminPaymentDetail reports), a reason, and refundReason customer|chargeback|error. A DIFFERENT staff member must approve it (decideApproval); approval then records the refund, takes back unused credits and queues the DIAN credit note. It does NOT move money: staff return it in the Wompi dashboard. Returns the approval request.

Parameters of adminRequestRefund
NameInTypeRequired
grossBodyobjectYes
paymentIdBodystring (uuid)Yes
reasonBodystring 3–1000Yes
refundReasonBody"customer" | "chargeback" | "error"No
curl
curl -X POST 'https://www.notificado.co/api/request-refunds/admin' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "gross": {
    "currency": "COP",
    "minor": 1
  },
  "paymentId": "<paymentId>",
  "reason": "<reason>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/request-refunds/admin', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "gross": {
      "currency": "COP",
      "minor": 1
    },
    "paymentId": "<paymentId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "amount": {
    "currency": "<currency>",
    "minor": -9007199254740991
  },
  "credits": -9007199254740991,
  "decidedAt": "2026-09-25T15:00:00Z",
  "decidedBy": "<decidedBy>",
  "decisionReason": "<decisionReason>",
  "executedRef": "<executedRef>",
  "expiresAt": "2026-09-25T15:00:00Z",
  "failureReason": "<failureReason>",
  "id": "<id>",
  "kind": "<kind>",
  "payload": {},
  "payloadSha256": "<payloadSha256>",
  "reason": "<reason>",
  "requestedAt": "2026-09-25T15:00:00Z",
  "requestedBy": "<requestedBy>",
  "status": "<status>",
  "subjectOrgId": "<subjectOrgId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

setSenderLimit

POST/api/sender-limits/set

Notificado staff onlyPermission: abuse:write

setSenderLimit

Parameters of setSenderLimit
NameInTypeRequired
orgIdBodystring 1–64Yes
perDayBodyinteger -9007199254740991–9007199254740991 | string 1–9Yes
perHourBodyinteger -9007199254740991–9007199254740991 | string 1–9Yes
reasonBodystring 1–500Yes
curl
curl -X POST 'https://www.notificado.co/api/sender-limits/set' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "orgId": "<orgId>",
  "perDay": -9007199254740991,
  "perHour": -9007199254740991,
  "reason": "<reason>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/sender-limits/set', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "perDay": -9007199254740991,
    "perHour": -9007199254740991,
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "orgId": "<orgId>",
  "perDay": -9007199254740991,
  "perHour": -9007199254740991,
  "reason": "<reason>",
  "setAt": "2026-09-25T15:00:00Z",
  "setBy": "<setBy>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmStaffAction

POST/api/staff-actions/confirm

Notificado staff onlyPermission: admin:tokens:self

confirmStaffAction

Parameters of confirmStaffAction
NameInTypeRequired
confirmationIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/staff-actions/confirm' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"confirmationId":"<confirmationId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-actions/confirm', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "confirmationId": "<confirmationId>"
  }),
});
const result = await response.json();
Example response
200
{
  "confirmationId": "<confirmationId>",
  "resultJson": "<resultJson>",
  "status": "confirmed",
  "tool": "<tool>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmStaffMfa

POST/api/staff-mfas/confirm

Notificado staff onlyPermission: admin:read

confirmStaffMfa

Parameters of confirmStaffMfa
NameInTypeRequired
codeBodystring 6–8Yes
secretBodystring 16–128Yes
curl
curl -X POST 'https://www.notificado.co/api/staff-mfas/confirm' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"code":"<code>","secret":"<secret>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-mfas/confirm', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "code": "<code>",
    "secret": "<secret>"
  }),
});
const result = await response.json();
Example response
200
{
  "recoveryCodes": [
    "<recoveryCodes>"
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

enrolStaffMfa

POST/api/staff-mfas/enrol

Notificado staff onlyPermission: admin:read

enrolStaffMfa

curl
curl -X POST 'https://www.notificado.co/api/staff-mfas/enrol' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-mfas/enrol', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "secret": "<secret>",
  "uri": "<uri>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

issueStaffToken

POST/api/staff-tokens/issue

Notificado staff onlyPermission: admin:tokens:self

issueStaffToken

Parameters of issueStaffToken
NameInTypeRequired
codeBodystring 1–64No
nameBodystring 1–100Yes
scopesBodyarray of string 1–40No
ttlHoursBody1 | 24 | 168Yes
curl
curl -X POST 'https://www.notificado.co/api/staff-tokens/issue' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"name":"<name>","ttlHours":1}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-tokens/issue', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "name": "<name>",
    "ttlHours": 1
  }),
});
const result = await response.json();
Example response
200
{
  "summary": {
    "createdAt": "2026-09-25T15:00:00Z",
    "createdAtBogota": "<createdAtBogota>",
    "expiresAt": "2026-09-25T15:00:00Z",
    "expiresAtBogota": "<expiresAtBogota>",
    "id": "<id>",
    "lastUsedAt": "2026-09-25T15:00:00Z",
    "lastUsedAtBogota": "<lastUsedAtBogota>",
    "name": "<name>",
    "own": true,
    "prefix": "<prefix>",
    "revokedAt": "2026-09-25T15:00:00Z",
    "revokedAtBogota": "<revokedAtBogota>",
    "scopes": [
      "staff:read"
    ],
    "status": "active",
    "userId": "<userId>"
  },
  "token": "<token>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listStaffTokens

POST/api/staff-tokens/list

Notificado staff onlyPermission: admin:tokens:self

listStaffTokens

Parameters of listStaffTokens
NameInTypeRequired
allBodybooleanNo
curl
curl -X POST 'https://www.notificado.co/api/staff-tokens/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-tokens/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "tokens": [
    {
      "createdAt": "2026-09-25T15:00:00Z",
      "createdAtBogota": "<createdAtBogota>",
      "expiresAt": "2026-09-25T15:00:00Z",
      "expiresAtBogota": "<expiresAtBogota>",
      "id": "<id>",
      "lastUsedAt": "2026-09-25T15:00:00Z",
      "lastUsedAtBogota": "<lastUsedAtBogota>",
      "name": "<name>",
      "own": true,
      "prefix": "<prefix>",
      "revokedAt": "2026-09-25T15:00:00Z",
      "revokedAtBogota": "<revokedAtBogota>",
      "scopes": [
        "staff:read"
      ],
      "status": "active",
      "userId": "<userId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeStaffToken

POST/api/staff-tokens/revoke

Notificado staff onlyPermission: or(admin:tokens:manage, admin:tokens:self)

revokeStaffToken

Parameters of revokeStaffToken
NameInTypeRequired
tokenIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/staff-tokens/revoke' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"tokenId":"<tokenId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/staff-tokens/revoke', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "tokenId": "<tokenId>"
  }),
});
const result = await response.json();
Example response
200
{
  "createdAt": "2026-09-25T15:00:00Z",
  "createdAtBogota": "<createdAtBogota>",
  "expiresAt": "2026-09-25T15:00:00Z",
  "expiresAtBogota": "<expiresAtBogota>",
  "id": "<id>",
  "lastUsedAt": "2026-09-25T15:00:00Z",
  "lastUsedAtBogota": "<lastUsedAtBogota>",
  "name": "<name>",
  "own": true,
  "prefix": "<prefix>",
  "revokedAt": "2026-09-25T15:00:00Z",
  "revokedAtBogota": "<revokedAtBogota>",
  "scopes": [
    "staff:read"
  ],
  "status": "active",
  "userId": "<userId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

checkStorageLock

POST/api/storage-locks/check

Notificado staff onlyPermission: admin:system:readMCP tool: checkStorageLock

Staff only. Reads the S3 Object Lock actually applied to one evidence object (one HEAD, never the content): mode COMPLIANCE | GOVERNANCE | NONE (or n/a on a local dev disk), retainUntil (UTC), legalHold. Omit key to check the newest stored timestamp token. In production alert is true, with alertReason, when the object is deletable. Audited.

Parameters of checkStorageLock
NameInTypeRequired
keyBodystring 1–512No
curl
curl -X POST 'https://www.notificado.co/api/storage-locks/check' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/storage-locks/check', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "alert": true,
  "alertReason": "<alertReason>",
  "backend": "local",
  "checkedAt": "2026-09-25T15:00:00Z",
  "defaulted": true,
  "key": "<key>",
  "legalHold": true,
  "mode": "COMPLIANCE",
  "production": true,
  "retainUntil": "2026-09-25T15:00:00Z"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

addSupportNote

POST/api/support-notes/add

Notificado staff onlyPermission: admin:support:writeMCP tool: addSupportNote

Staff only (superadmin, ops, support, compliance). Append a support note to one customer org: what happened and what was agreed (up to 4000 characters). Notes are staff-only, insert-only (never edited or deleted — write a new note to correct one) and shown on the org 360. Through MCP the call waits for your human to confirm it in /admin/mcp. Audited.

Parameters of addSupportNote
NameInTypeRequired
bodyBodystring 1–4000Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/support-notes/add' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"body":"<body>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/support-notes/add', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "body": "<body>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "authorId": "<authorId>",
  "authorRole": "<authorRole>",
  "body": "<body>",
  "createdAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "orgId": "<orgId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listSupportNotes

POST/api/support-notes/list

Notificado staff onlyPermission: admin:orgs:readMCP tool: listSupportNotes

Staff only. One customer org's staff support notes (author id and role, text, when), newest first; page with cursor. Every call is audited.

Parameters of listSupportNotes
NameInTypeRequired
cursorBodystring 1–200No
limitBodyinteger 1–100No
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/support-notes/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/support-notes/list', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "nextCursor": "<nextCursor>",
  "rows": [
    {
      "authorId": "<authorId>",
      "authorRole": "<authorRole>",
      "body": "<body>",
      "createdAt": "2026-09-25T15:00:00Z",
      "id": "<id>",
      "orgId": "<orgId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

liftSuspension

POST/api/suspensions/lift

Notificado staff onlyPermission: abuse:write

liftSuspension

Parameters of liftSuspension
NameInTypeRequired
noteBodystring 3–1000Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/suspensions/lift' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"note":"<note>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/suspensions/lift', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "note": "<note>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "liftedAt": "2026-09-25T15:00:00Z",
  "liftedBy": "<liftedBy>",
  "orgId": "<orgId>",
  "reason": "<reason>",
  "suspendedAt": "2026-09-25T15:00:00Z",
  "suspendedBy": "<suspendedBy>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

triggerTestError

POST/api/test-errors/trigger

Notificado staff onlyPermission: admin:ops:test-error

triggerTestError

Parameters of triggerTestError
NameInTypeRequired
noteBodystring 1–200No
curl
curl -X POST 'https://www.notificado.co/api/test-errors/trigger' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/test-errors/trigger', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "raised": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID