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
GET /_x/query/abuse-overview
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required orgIdQuery string (uuid)No _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/abuse-overview' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/abuse-overview' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/admin-affiliates
Notificado staff only Permission: affiliate:admin
adminAffiliates
Parameters of adminAffiliates Name In Type Required limitQuery integer 1–500No statusQuery "applied" | "approved" | "suspended" | "closed"No _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/admin-affiliates' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/admin-affiliates' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/admin-payout-batches
Notificado staff only Permission: affiliate:admin MCP 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 Name In Type Required limitQuery integer 1–60No _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/admin-payout-batches' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/admin-payout-batches' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/admin-withholding-rates
Notificado staff only Permission: affiliate:admin MCP 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 Name In Type Required limitQuery integer 1–200No _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/admin-withholding-rates' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/admin-withholding-rates' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/billing-kpis
Notificado staff only Permission: admin:kpi:read MCP 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 Name In Type Required fromQuery string (date-time)Yes toQuery string (date-time)Yes _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/billing-kpis?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
-b cookies.txtTypeScript Copy 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 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/catalog-snapshot
Notificado staff only Permission: admin:config:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/catalog-snapshot' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/catalog-snapshot' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/deliverability
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required fromQuery string (date-time)Yes toQuery string (date-time)Yes _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/deliverability?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
-b cookies.txtTypeScript Copy 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 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/evidence-health
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/evidence-health' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/evidence-health' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/funnel-report
Notificado staff only Permission: admin:kpi:read MCP 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 Name In Type Required fromQuery string (date-time)Yes toQuery string (date-time)Yes _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/funnel-report?from=2026-09-25T15:00:00Z&to=2026-09-25T15:00:00Z' \
-b cookies.txtTypeScript Copy 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 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/job-queues
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/job-queues' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/job-queues' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/kpi-snapshot
Notificado staff only Permission: admin:kpi:read MCP 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 Name In Type Required monthQuery string 7–7Yes _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/kpi-snapshot?month=<month>' \
-b cookies.txtTypeScript Copy 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 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/ops-alerts
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/ops-alerts' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/ops-alerts' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/ops-overview
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/ops-overview' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/ops-overview' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/orphan-approvals
Notificado staff only Permission: admin:payments:read MCP 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 Name In Type Required limitQuery integer 1–500No _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/orphan-approvals' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/orphan-approvals' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/pending-staff-confirmations
Notificado staff only Permission: admin:tokens:self
pendingStaffConfirmations
Parameters of pendingStaffConfirmations Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/pending-staff-confirmations' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/pending-staff-confirmations' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/preview-payout-batch
Notificado staff only Permission: affiliate:admin MCP 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 Name In Type Required periodQuery string 7–7Yes _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/preview-payout-batch?period=<period>' \
-b cookies.txtTypeScript Copy 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 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied GET /_x/query/provider-health
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required _firstQuery integer 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000) No _afterQuery stringthe endCursor a previous page answered; needs _first No
curl Copy curl 'https://www.notificado.co/_x/query/provider-health' \
-b cookies.txtTypeScript Copy const response = await fetch('https://www.notificado.co/_x/query/provider-health' , {
headers : { cookie : sessionCookie },
});
const result = await response.json();Example response 200 Copy [
null
]Errors
400 X_INPUT_INVALID or X_CURSOR_INVALID 403 policy denied POST /api/affiliate-documents/view
Notificado staff only Permission: affiliate:admin
viewAffiliateDocument
Parameters of viewAffiliateDocument Name In Type Required affiliateIdBody string (uuid)Yes fileBody "rut" | "bank_cert"Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/affiliates/review
Notificado staff only Permission: affiliate:admin
reviewAffiliate
Parameters of reviewAffiliate Name In Type Required affiliateIdBody string (uuid)Yes decisionBody "approve" | "reject" | "suspend" | "reinstate"Yes reasonBody string 1–500No
curl Copy 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 Copy 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 Copy {
"affiliateId": "<affiliateId>",
"kycStatus": "pending",
"status": "applied"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/approvals/decide
Notificado staff only Permission: admin:approvals:decide
decideApproval
Parameters of decideApproval Name In Type Required codeBody string 1–64No decisionBody "approve" | "reject"Yes idBody string (uuid)Yes reasonBody string 1–1000No
curl Copy 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 Copy 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 Copy {
"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 POST /api/approvals/list
Notificado staff only Permission: admin:approvals:read MCP 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 Name In Type Required cursorBody string 1–200No limitBody integer 1–200No statusBody "pending" | "approved" | "rejected" | "executed" | "failed" | "expired"No subjectOrgIdBody string (uuid)No
curl Copy 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 Copy 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 Copy {
"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 POST /api/archive-coupons/admin
Notificado staff only Permission: admin:coupons:write MCP 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 Name In Type Required couponIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/as-orgs/view
Notificado staff only Permission: admin:customer-data:read MCP 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 Name In Type Required orgIdBody string (uuid)Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/audits/export
Notificado staff only Permission: admin:audit:export MCP 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 Name In Type Required actorIdBody string 1–120No fromBody string 1–10Yes outcomeBody "allowed" | "denied" | "failed"No subjectIdBody string 1–120No subjectOrgIdBody string (uuid)No subjectTypeBody string 1–64No toBody string 1–10Yes
curl Copy 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 Copy 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 Copy {
"bytes": 0,
"contentBase64": "<contentBase64>",
"contentType": "<contentType>",
"filename": "<filename>",
"rows": 0,
"sha256": "<sha256>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/audits/list
Notificado staff only Permission: admin:audit:read MCP 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 Name In Type Required actorIdBody string 1–120No cursorBody string 1–24No fromBody string (date-time)No limitBody integer 1–500No outcomeBody "allowed" | "denied" | "failed"No subjectIdBody string 1–120No subjectOrgIdBody string (uuid)No subjectTypeBody string 1–64No toBody string (date-time)No
curl Copy 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 Copy 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 Copy {
"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 POST /api/create-coupons/admin
Notificado staff only Permission: admin:coupons:write MCP 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 Name In Type Required Idempotency-KeyQuery string ≤ 255Replays the first response for a repeated key. No amountOffBody objectinteger minor units plus an ISO 4217 currency code No appliesToBody "pack" | "subscription" | "any"Yes campaignBody string 1–80No codeBody string 3–40Yes cyclesBody integer 1–120No durationBody "once" | "cycles" | "forever"Yes firstPurchaseOnlyBody booleanNo kindBody "percent" | "fixed"Yes maxRedemptionsBody integer 1–9007199254740991No percentBpsBody integer 1–10000No validFromBody string (date-time)No validToBody string (date-time)No
curl Copy 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 Copy 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 Copy {
"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 POST /api/customer360s/view
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required orgIdBody string (uuid)Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/download-affiliate-support-documents/admin
Notificado staff only Permission: affiliate:admin
adminDownloadAffiliateSupportDocument
Parameters of adminDownloadAffiliateSupportDocument Name In Type Required formatBody "pdf" | "xml"No payoutIdBody string (uuid)Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"contentBase64": "<contentBase64>",
"contentType": "<contentType>",
"filename": "<filename>",
"sha256": "<sha256>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/download-gateway-events/admin
Notificado staff only Permission: admin:payments:read MCP 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 Name In Type Required eventIdBody string (uuid)Yes purposeBody string 1–500No
curl Copy 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 Copy 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 Copy {
"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 POST /api/dsr-queues/list
Notificado staff only Permission: admin:dsr:read MCP 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 Name In Type Required limitBody integer 1–200Yes stateBody "open" | "closed" | "all"Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/dsrs/extend
Notificado staff only Permission: admin:dsr:write
extendDsr
Parameters of extendDsr Name In Type Required idBody string (uuid)Yes reasonBody string 10–1000Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/dsrs/respond
Notificado staff only Permission: admin:dsr:write
respondDsr
Parameters of respondDsr Name In Type Required idBody string (uuid)Yes messageBody string 10–10000Yes outcomeBody "answered" | "granted" | "partially_granted" | "retained_legal_basis" | "forwarded_to_responsable" | "incomplete" | "denied"Yes responsableOrgIdBody string (uuid)No touchesEvidenceBody "yes" | "no"Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/export-evidence-zips/admin
Notificado staff only Permission: admin:evidence:export MCP 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 Name In Type Required confirmTokenBody string 1–200No notificationIdBody string (uuid)Yes purposeBody string 1–500Yes versionBody integer 1–9007199254740991No
curl Copy 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 Copy 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 Copy {
"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 POST /api/incident-updates/post
Notificado staff only Permission: admin:incident:write MCP 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 Name In Type Required idBody string (uuid)Yes impactBody "maintenance" | "degraded" | "partial_outage" | "major_outage" | ""No messageBody string 3–2000Yes messageEnBody string 0–2000No statusBody "investigating" | "identified" | "monitoring"Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/incidents/create
Notificado staff only Permission: admin:incident:write MCP 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 Name In Type Required impactBody "maintenance" | "degraded" | "partial_outage" | "major_outage"Yes messageBody string 3–2000Yes messageEnBody string 0–2000No startedAtBody string (date-time)No titleBody string 3–200Yes titleEnBody string 0–200No
curl Copy 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 Copy 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 Copy {
"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 POST /api/incidents/resolve
Notificado staff only Permission: admin:incident:write MCP 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 Name In Type Required idBody string (uuid)Yes messageBody string 3–2000Yes messageEnBody string 0–2000No
curl Copy 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 Copy 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 Copy {
"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 POST /api/jobs/cancel
Notificado staff only Permission: admin:jobs:write
cancelJob
Parameters of cancelJob Name In Type Required confirmBody string 1–220Yes jobIdBody string 1–200Yes reasonBody string 1–500No
curl Copy 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 Copy 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 Copy {
"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 POST /api/jobs/requeue
Notificado staff only Permission: admin:jobs:write MCP 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 Name In Type Required fromStepBody string 1–200No jobIdBody string 1–200Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/kyc-documents/view
Notificado staff only Permission: kyc:review
viewKycDocument
Parameters of viewKycDocument Name In Type Required profileIdBody string (uuid)Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/kyc-queues/list
Notificado staff only Permission: kyc:review MCP 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 Name In Type Required limitBody integer 1–200No
curl Copy 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 Copy 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 Copy [
{
"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 POST /api/kycs/approve
Notificado staff only Permission: kyc:review MCP 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 Name In Type Required documentIdBody string (uuid)No orgIdBody string (uuid)Yes profileIdBody string (uuid)Yes reasonBody string 1–2000Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/kycs/reject
Notificado staff only Permission: kyc:review MCP 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 Name In Type Required documentIdBody string (uuid)No orgIdBody string (uuid)Yes profileIdBody string (uuid)Yes reasonBody string 1–2000Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/ledger-lists/staff
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required cursorBody string 1–200No limitBody integer 1–200No orgIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/list-coupons/admin
Notificado staff only Permission: admin:coupons:read MCP 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 Name In Type Required campaignBody string 1–80No includeArchivedBody booleanNo limitBody integer 1–500No
curl Copy 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 Copy 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 Copy {
"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 POST /api/list-payments/admin
Notificado staff only Permission: admin:payments:read MCP 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 Name In Type Required cursorBody string 1–200No fromBody string (date-time)No limitBody integer 1–200Yes orgIdBody string (uuid)No qBody string 1–120No statusBody "created" | "pending" | "approved" | "declined" | "voided" | "error" | "refunded" | "partially_refunded"No toBody string (date-time)No
curl Copy 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 Copy 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 Copy {
"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 POST /api/manual-invoice-uploads/request
Notificado staff only Permission: admin:invoicing:issue MCP 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 Name In Type Required filenameBody string 1–255Yes sizeBody integer 0–9007199254740991No
curl Copy 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 Copy 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 Copy {
"contentType": "<contentType>",
"expiresAt": -9007199254740991,
"key": "<key>",
"maxBytes": -9007199254740991,
"method": "PUT",
"url": "<url>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/manual-invoices/pending
Notificado staff only Permission: admin:invoicing:issue MCP 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 Name In Type Required limitBody integer 1–500No
curl Copy 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 Copy 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 Copy {
"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 POST /api/manual-invoices/record
Notificado staff only Permission: admin:invoicing:issue MCP 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 Name In Type Required codeBody stringYes documentBody "invoice" | "credit_note"Yes idBody string (uuid)Yes issuedAtBody string (date-time)Yes numberBody stringYes orgIdBody string (uuid)Yes pdfKeyBody string 1–512Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/manual-payouts/record
Notificado staff only Permission: affiliate:admin
recordManualPayout
Parameters of recordManualPayout Name In Type Required noteBody string 1–500No outcomeBody "paid" | "failed"Yes payoutIdBody string (uuid)Yes referenceBody string 1–64No
curl Copy 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 Copy 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 Copy {
"payoutId": "<payoutId>",
"reference": "<reference>",
"status": "<status>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/notifications/search
Notificado staff only Permission: admin:customer-data:read MCP 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 Name In Type Required cursorBody string 1–200No limitBody integer 1–100No termBody string 1–320Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/orgs/search
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required cursorBody string 1–200No limitBody integer 1–100No termBody string 1–200Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/orgs/suspend
Notificado staff only Permission: abuse:write
suspendOrg
Parameters of suspendOrg Name In Type Required orgIdBody string (uuid)Yes reasonBody string 3–1000Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/orgs/view
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required orgIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/payment-details/admin
Notificado staff only Permission: admin:payments:read MCP 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 Name In Type Required paymentIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/payout-batches/create
Notificado staff only Permission: affiliate:admin
createPayoutBatch
Parameters of createPayoutBatch Name In Type Required periodBody string 7–7Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/raw-events/view
Notificado staff only Permission: admin:customer-data:read MCP 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 Name In Type Required eventIdBody string (uuid)Yes purposeBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/recipient-timelines/view
Notificado staff only Permission: admin:customer-data:read MCP 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 Name In Type Required purposeBody string 1–500No recipientIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/reconcile-payments/admin
Notificado staff only Permission: admin:payments:read MCP 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 Name In Type Required paymentIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"enqueued": true,
"orgId": "<orgId>",
"paymentId": "<paymentId>",
"status": "created"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/reissue-constancias/admin
Notificado staff only Permission: admin:evidence:reissue MCP 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 Name In Type Required confirmTokenBody string 1–200No notificationIdBody string (uuid)Yes reasonBody string 1–1000Yes
curl Copy 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 Copy 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 Copy {
"notificationId": "<notificationId>",
"orgId": "<orgId>",
"queued": true,
"version": 2
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/request-refunds/admin
Notificado staff only Permission: admin:payments:refund MCP 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 Name In Type Required grossBody objectYes paymentIdBody string (uuid)Yes reasonBody string 3–1000Yes refundReasonBody "customer" | "chargeback" | "error"No
curl Copy 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 Copy 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 Copy {
"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 POST /api/sender-limits/set
Notificado staff only Permission: abuse:write
setSenderLimit
Parameters of setSenderLimit Name In Type Required orgIdBody string 1–64Yes perDayBody integer -9007199254740991–9007199254740991 | string 1–9Yes perHourBody integer -9007199254740991–9007199254740991 | string 1–9Yes reasonBody string 1–500Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/staff-actions/confirm
Notificado staff only Permission: admin:tokens:self
confirmStaffAction
Parameters of confirmStaffAction Name In Type Required confirmationIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"confirmationId": "<confirmationId>",
"resultJson": "<resultJson>",
"status": "confirmed",
"tool": "<tool>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/staff-mfas/confirm
Notificado staff only Permission: admin:read
confirmStaffMfa
Parameters of confirmStaffMfa Name In Type Required codeBody string 6–8Yes secretBody string 16–128Yes
curl Copy 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 Copy 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 Copy {
"recoveryCodes": [
"<recoveryCodes>"
]
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/staff-mfas/enrol
Notificado staff only Permission: admin:read
enrolStaffMfa
curl Copy 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 Copy 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 Copy {
"secret": "<secret>",
"uri": "<uri>"
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID POST /api/staff-tokens/issue
Notificado staff only Permission: admin:tokens:self
issueStaffToken
Parameters of issueStaffToken Name In Type Required codeBody string 1–64No nameBody string 1–100Yes scopesBody array of string 1–40No ttlHoursBody 1 | 24 | 168Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/staff-tokens/list
Notificado staff only Permission: admin:tokens:self
listStaffTokens
Parameters of listStaffTokens Name In Type Required allBody booleanNo
curl Copy 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 Copy 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 Copy {
"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 POST /api/staff-tokens/revoke
Notificado staff only Permission: or(admin:tokens:manage, admin:tokens:self)
revokeStaffToken
Parameters of revokeStaffToken Name In Type Required tokenIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/storage-locks/check
Notificado staff only Permission: admin:system:read MCP 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 Name In Type Required keyBody string 1–512No
curl Copy 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 Copy 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 Copy {
"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 POST /api/support-notes/add
Notificado staff only Permission: admin:support:write MCP 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 Name In Type Required bodyBody string 1–4000Yes orgIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/support-notes/list
Notificado staff only Permission: admin:orgs:read MCP 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 Name In Type Required cursorBody string 1–200No limitBody integer 1–100No orgIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/suspensions/lift
Notificado staff only Permission: abuse:write
liftSuspension
Parameters of liftSuspension Name In Type Required noteBody string 3–1000Yes orgIdBody string (uuid)Yes
curl Copy 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 Copy 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 Copy {
"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 POST /api/test-errors/trigger
Notificado staff only Permission: admin:ops:test-error
triggerTestError
Parameters of triggerTestError Name In Type Required noteBody string 1–200No
curl Copy 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 Copy 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 Copy {
"raised": true
}Errors
400 X_INPUT_INVALID 403 policy denied 422 X_BODY_INVALID