Skip to content
Notificado

Technical reference

API reference

154 operations, generated from Notificado's OpenAPI document. Each one has its own link, its parameters and examples ready to copy.

Authentication

The HTTP routes answer for a user's session: sign in with the example below and send the stored cookie on every call (-b cookies.txt).

Writes (POST) made outside a browser must state the origin with -H 'origin: https://www.notificado.co'; without it they are refused with X_CSRF_BLOCKED.

In the TypeScript examples, sessionCookie is the name=value pair of the cookie your sign-in answered.

Agent tokens work only on the MCP server, not on these routes. MCP server · Authentication guide

Each operation's description is in English: it is what the system itself declares, the same text AI assistants read.

curl
curl -c cookies.txt -X POST 'https://www.notificado.co/api/ins/sign' \
  -H 'content-type: application/json' \
  -d '{"email":"<email>","password":"<password>"}'

Sign-in and account

signIn

POST/api/ins/sign

No sessionPermission: auth:anonymous

signIn

Parameters of signIn
NameInTypeRequired
codeBodystring 0–64No
emailBodystring 1–320Yes
nextBodystring 0–2048No
passwordBodystring 1–1024Yes
curl
curl -X POST 'https://www.notificado.co/api/ins/sign' \
  -H 'content-type: application/json' \
  -d '{"email":"<email>","password":"<password>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/ins/sign', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "email": "<email>",
    "password": "<password>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true,
  "userId": "<userId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

signOut

POST/api/outs/sign

Firm memberPermission: auth:sign-out

signOut

curl
curl -X POST 'https://www.notificado.co/api/outs/sign' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/outs/sign', {
  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
{
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requestPasswordReset

POST/api/password-resets/request

No sessionPermission: auth:anonymous

requestPasswordReset

Parameters of requestPasswordReset
NameInTypeRequired
captchaTokenBodystring 0–4096No
cf-turnstile-responseBodystring 0–4096No
emailBodystring 0–320Yes
h-captcha-responseBodystring 0–4096No
localeBodystring 0–16No
curl
curl -X POST 'https://www.notificado.co/api/password-resets/request' \
  -H 'content-type: application/json' \
  -d '{"email":"<email>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/password-resets/request', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "email": "<email>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

resetPassword

POST/api/passwords/reset

No sessionPermission: auth:anonymous

resetPassword

Parameters of resetPassword
NameInTypeRequired
passwordBodystring 0–1024Yes
passwordConfirmBodystring 0–1024No
tokenBodystring 0–2048Yes
curl
curl -X POST 'https://www.notificado.co/api/passwords/reset' \
  -H 'content-type: application/json' \
  -d '{"password":"<password>","token":"<token>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/passwords/reset', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "password": "<password>",
    "token": "<token>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

signUp

POST/api/ups/sign

No sessionPermission: auth:anonymous

signUp

Parameters of signUp
NameInTypeRequired
captchaTokenBodystring 0–4096No
cf-turnstile-responseBodystring 0–4096No
emailBodystring 1–320Yes
h-captcha-responseBodystring 0–4096No
nameBodystring 1–200Yes
nextBodystring 0–2048No
orgNameBodystring 1–200Yes
passwordBodystring 1–1024Yes
referralCodeBodystring 0–40No
termsVersionBodystring 1–64No
curl
curl -X POST 'https://www.notificado.co/api/ups/sign' \
  -H 'content-type: application/json' \
  -d '{
  "email": "<email>",
  "name": "<name>",
  "orgName": "<orgName>",
  "password": "<password>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/ups/sign', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "email": "<email>",
    "name": "<name>",
    "orgName": "<orgName>",
    "password": "<password>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true,
  "orgId": "<orgId>",
  "userId": "<userId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Firm and members

memberList

GET/_x/query/member-list

Firm memberPermission: org:read

memberList

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

myMfa

GET/_x/query/my-mfa

Firm memberPermission: org:read

myMfa

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

myOrgs

GET/_x/query/my-orgs

Firm memberPermission: org:read

myOrgs

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

myPreferences

GET/_x/query/my-preferences

Firm memberPermission: org:read

myPreferences

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

mySessions

GET/_x/query/my-sessions

Firm memberPermission: org:read

mySessions

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

pendingInvites

GET/_x/query/pending-invites

Firm memberPermission: org:manage

pendingInvites

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

seatUsage

GET/_x/query/seat-usage

Firm memberPermission: org:read

seatUsage

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

acceptInvite

POST/api/invites/accept

Firm memberPermission: org:accept-invite

acceptInvite

Parameters of acceptInvite
NameInTypeRequired
tokenBodystring 1–2048Yes
curl
curl -X POST 'https://www.notificado.co/api/invites/accept' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"token":"<token>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/invites/accept', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "token": "<token>"
  }),
});
const result = await response.json();
Example response
200
{
  "orgId": "<orgId>",
  "redirectTo": "<redirectTo>",
  "role": "<role>",
  "status": "joined"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeInvite

POST/api/invites/revoke

Firm memberPermission: org:manage

revokeInvite

Parameters of revokeInvite
NameInTypeRequired
idBodystring 1–64Yes
curl
curl -X POST 'https://www.notificado.co/api/invites/revoke' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"id":"<id>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/invites/revoke', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "id": "<id>"
  }),
});
const result = await response.json();
Example response
200
{
  "email": "<email>",
  "id": "<id>",
  "role": "<role>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

setMemberRole

POST/api/member-roles/set

Firm memberPermission: org:manage

setMemberRole

Parameters of setMemberRole
NameInTypeRequired
roleBody"owner" | "lawyer" | "paralegal" | "billing" | "viewer"Yes
userIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/member-roles/set' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"role":"owner","userId":"<userId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/member-roles/set', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "role": "owner",
    "userId": "<userId>"
  }),
});
const result = await response.json();
Example response
200
{
  "createdAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "role": "owner",
  "userId": "<userId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

inviteMember

POST/api/members/invite

Firm memberPermission: org:manage

inviteMember

Parameters of inviteMember
NameInTypeRequired
emailBodystring (email) ≤ 320Yes
roleBody"owner" | "lawyer" | "paralegal" | "billing" | "viewer"Yes
curl
curl -X POST 'https://www.notificado.co/api/members/invite' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"email":"<email>","role":"owner"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/members/invite', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "email": "<email>",
    "role": "owner"
  }),
});
const result = await response.json();
Example response
200
{
  "email": "<email>",
  "expiresAt": "2026-09-25T15:00:00Z",
  "role": "<role>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

removeMember

POST/api/members/remove

Firm memberPermission: org:manage

removeMember

Parameters of removeMember
NameInTypeRequired
userIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/members/remove' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"userId":"<userId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/members/remove', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "userId": "<userId>"
  }),
});
const result = await response.json();
Example response
200
{
  "createdAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "role": "owner",
  "userId": "<userId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmMfa

POST/api/mfas/confirm

Firm memberPermission: org:read

confirmMfa

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

disableMfa

POST/api/mfas/disable

Firm memberPermission: org:read

disableMfa

Parameters of disableMfa
NameInTypeRequired
codeBodystring 6–64Yes
passwordBodystring 1–1024Yes
curl
curl -X POST 'https://www.notificado.co/api/mfas/disable' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"code":"<code>","password":"<password>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/mfas/disable', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "code": "<code>",
    "password": "<password>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

enrolMfa

POST/api/mfas/enrol

Firm memberPermission: org:read

enrolMfa

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

switchOrg

POST/api/orgs/switch

Firm memberPermission: org:read

switchOrg

Parameters of switchOrg
NameInTypeRequired
nextBodystring 1–2048No
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/orgs/switch' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/orgs/switch', {
  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
{
  "orgId": "<orgId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeOtherSessions

POST/api/other-sessions/revoke

Firm memberPermission: org:read

revokeOtherSessions

curl
curl -X POST 'https://www.notificado.co/api/other-sessions/revoke' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/other-sessions/revoke', {
  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
{
  "revoked": 1
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

setPreferences

POST/api/preferences/set

Firm memberPermission: org:read

setPreferences

Parameters of setPreferences
NameInTypeRequired
localeBody"es-co" | "en" | "auto" | nullNo
returnToBodystring 1–2048No
themeBody"system" | "light" | "dark"No
curl
curl -X POST 'https://www.notificado.co/api/preferences/set' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/preferences/set', {
  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
{
  "locale": "es-co",
  "theme": "system"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

setRequireMfa

POST/api/require-mfas/set

Firm memberPermission: org:manage

setRequireMfa

Parameters of setRequireMfa
NameInTypeRequired
requireMfaBody"on" | "off"Yes
curl
curl -X POST 'https://www.notificado.co/api/require-mfas/set' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"requireMfa":"on"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/require-mfas/set', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "requireMfa": "on"
  }),
});
const result = await response.json();
Example response
200
{
  "requireMfa": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeSession

POST/api/sessions/revoke

Firm memberPermission: org:read

revokeSession

Parameters of revokeSession
NameInTypeRequired
sessionIdBodystring 1–64Yes
curl
curl -X POST 'https://www.notificado.co/api/sessions/revoke' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"sessionId":"<sessionId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/sessions/revoke', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "sessionId": "<sessionId>"
  }),
});
const result = await response.json();
Example response
200
{
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Lawyer verification

myKyc

GET/_x/query/my-kyc

Firm memberPermission: kyc:submit

myKyc

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

submitKyc

POST/api/kycs/submit

Firm memberPermission: kyc:submit

submitKyc

Parameters of submitKyc
NameInTypeRequired
cedulaBodystring 5–12Yes
fullNameBodystring 1–200Yes
sirnaEmailBodystring (email) ≤ 320Yes
tarjetaProfesionalBodystring 1–12Yes
vigenciaDocumentIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/kycs/submit' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "cedula": "<cedula>",
  "fullName": "<fullName>",
  "sirnaEmail": "<sirnaEmail>",
  "tarjetaProfesional": "<tarjetaProfesional>",
  "vigenciaDocumentId": "<vigenciaDocumentId>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/kycs/submit', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "cedula": "<cedula>",
    "fullName": "<fullName>",
    "sirnaEmail": "<sirnaEmail>",
    "tarjetaProfesional": "<tarjetaProfesional>",
    "vigenciaDocumentId": "<vigenciaDocumentId>"
  }),
});
const result = await response.json();
Example response
200
{
  "profileId": "<profileId>",
  "resubmitted": true,
  "status": "<status>",
  "warnings": [
    "<warnings>"
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmUpload

POST/api/uploads/confirm

Firm memberPermission: or(kyc:submit, case:write)MCP tool: confirmUpload

Step 2 of 2 of an upload, after the PUT to requestUpload's url succeeded: pass the same key, kind, filename and contentType. The server reads back the STORED bytes, checks their real type (PDF, PNG or JPEG) and size, computes the SHA-256 and returns the document (id, sha256, bytes). Use the id with attachDocument. Refused when the PUT never landed or the bytes are not what was granted — re-run requestUpload rather than retrying.

Parameters of confirmUpload
NameInTypeRequired
contentTypeBodystring 1–127Yes
filenameBodystring 1–255Yes
keyBodystring 1–512Yes
kindBody"certificado_vigencia" | "cedula" | "tarjeta_profesional" | "provenance_proof" | "otro"Yes
curl
curl -X POST 'https://www.notificado.co/api/uploads/confirm' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "contentType": "<contentType>",
  "filename": "<filename>",
  "key": "<key>",
  "kind": "certificado_vigencia"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/uploads/confirm', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "contentType": "<contentType>",
    "filename": "<filename>",
    "key": "<key>",
    "kind": "certificado_vigencia"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": -9007199254740991,
  "createdAt": "2026-09-25T15:00:00Z",
  "filename": "<filename>",
  "id": "<id>",
  "kind": "certificado_vigencia",
  "mime": "<mime>",
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requestUpload

POST/api/uploads/request

Firm memberPermission: or(kyc:submit, case:write)MCP tool: requestUpload

Step 1 of 2 of an upload: get a signed, single-use PUT grant for ONE file. Pass kind (use "otro" for a notification attachment; certificado_vigencia | cedula | tarjeta_profesional are KYC files; provenance_proof proves where a recipient address came from), filename, contentType (application/pdf | image/png | image/jpeg) and size in bytes (at most 20 MB). Then HTTP PUT the raw bytes to `url` (prefix a path with the server origin) with header Content-Type exactly `contentType`, before `expiresAt` (epoch ms), and call confirmUpload with the returned `key`. Never send file bytes through this tool.

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Cases and documents

caseDetail

GET/_x/query/case-detail

Firm memberPermission: case:readMCP tool: caseDetail

One case of the caller's firm by caseId (from caseList): 23-digit radicado, juzgado and its email, ciudad, especialidad, clase de proceso, cliente, its parties (role demandante | demandado | apoderado | otro, name, idNumber) and `locked` — true once a notification of it left draft, after which the case can no longer be edited. Returns no row for an id this firm does not have. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

caseList

GET/_x/query/case-list

Firm memberPermission: case:readMCP tool: caseList

The caller's firm's cases (procesos), newest first: id, 23-digit radicado, juzgado, ciudad, especialidad, clase de proceso and cliente. Use the id with caseDetail, or to start a notification on that case.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

checkAddress

POST/api/address/check

Firm memberPermission: case:writeMCP tool: checkAddress

Check an email address BEFORE adding it as a recipient: syntax, disposable (throwaway) domain, role account (info@, notificaciones@), a likely typo of a common provider (gmial.com → gmail.com, returned as `suggestion`), and whether the domain has a mail server (MX lookup, 3 s). Returns verdict ok | warn | block with `reasons`. A `block` address cannot be added or sent to; on `warn`, show the reasons to the lawyer. Each call is recorded as diligence evidence. Read-only for the address itself — it sends nothing.

Parameters of checkAddress
NameInTypeRequired
emailBodystring 1–320Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/address/check' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"email":"<email>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/address/check', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "email": "<email>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "checkedAt": "2026-09-25T15:00:00Z",
  "disposable": true,
  "email": "<email>",
  "id": "<id>",
  "mx": "<mx>",
  "reasons": [
    "<reasons>"
  ],
  "roleAccount": true,
  "suggestion": "<suggestion>",
  "syntaxOk": true,
  "verdict": "ok"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

detachAttachment

POST/api/attachments/detach

Firm memberPermission: case:write

detachAttachment

Parameters of detachAttachment
NameInTypeRequired
attachmentIdBodystring (uuid)Yes
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/attachments/detach' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "attachmentId": "<attachmentId>",
  "notificationId": "<notificationId>",
  "orgId": "<orgId>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/attachments/detach', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "attachmentId": "<attachmentId>",
    "notificationId": "<notificationId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": -9007199254740991,
  "filename": "<filename>",
  "id": "<id>",
  "kind": "auto_admisorio",
  "mime": "<mime>",
  "position": -9007199254740991,
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

createCase

POST/api/cases/create

Firm memberPermission: case:writeMCP tool: createCase

Create a case (proceso) in the caller's firm. `radicado` is the 23-digit Código Único de Radicación exactly as printed on the auto (dashes/spaces allowed) and is validated for structure; `juzgado` and `juzgadoEmail` are the court's name and buzón as listed in the CSJ directory; `cliente` is the firm's client. Refuses X_CASE_RADICADO_TAKEN when the firm already has that radicado — use the returned case id instead.

Parameters of createCase
NameInTypeRequired
ciudadBodystring 1–120Yes
claseProcesoBodystring 1–200Yes
clienteBodystring 1–300Yes
especialidadBodystring 1–120Yes
juzgadoBodystring 1–300Yes
juzgadoEmailBodystring (email) ≤ 320Yes
radicadoBodystring 23–40Yes
curl
curl -X POST 'https://www.notificado.co/api/cases/create' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "ciudad": "<ciudad>",
  "claseProceso": "<claseProceso>",
  "cliente": "<cliente>",
  "especialidad": "<especialidad>",
  "juzgado": "<juzgado>",
  "juzgadoEmail": "<juzgadoEmail>",
  "radicado": "<radicado>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/cases/create', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "ciudad": "<ciudad>",
    "claseProceso": "<claseProceso>",
    "cliente": "<cliente>",
    "especialidad": "<especialidad>",
    "juzgado": "<juzgado>",
    "juzgadoEmail": "<juzgadoEmail>",
    "radicado": "<radicado>"
  }),
});
const result = await response.json();
Example response
200
{
  "ciudad": "<ciudad>",
  "claseProceso": "<claseProceso>",
  "cliente": "<cliente>",
  "createdAt": "2026-09-25T15:00:00Z",
  "especialidad": "<especialidad>",
  "id": "<id>",
  "juzgado": "<juzgado>",
  "juzgadoEmail": "<juzgadoEmail>",
  "radicado": "<radicado>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

updateCase

POST/api/cases/update

Firm memberPermission: case:writeMCP tool: updateCase

Correct a case of the caller's firm: pass caseId and only the fields to change (radicado — 23 digits, dashes/spaces allowed —, juzgado, juzgadoEmail, ciudad, especialidad, claseProceso, cliente). Refused X_CASE_LOCKED once a notification of the case left draft: what was sent is evidence. Do not use it to register a different proceso — use createCase.

Parameters of updateCase
NameInTypeRequired
caseIdBodystring (uuid)Yes
ciudadBodystring 1–120No
claseProcesoBodystring 1–200No
clienteBodystring 1–300No
especialidadBodystring 1–120No
juzgadoBodystring 1–300No
juzgadoEmailBodystring (email) ≤ 320No
radicadoBodystring 23–40No
curl
curl -X POST 'https://www.notificado.co/api/cases/update' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"caseId":"<caseId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/cases/update', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "caseId": "<caseId>"
  }),
});
const result = await response.json();
Example response
200
{
  "ciudad": "<ciudad>",
  "claseProceso": "<claseProceso>",
  "cliente": "<cliente>",
  "createdAt": "2026-09-25T15:00:00Z",
  "especialidad": "<especialidad>",
  "id": "<id>",
  "juzgado": "<juzgado>",
  "juzgadoEmail": "<juzgadoEmail>",
  "radicado": "<radicado>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

attachDocument

POST/api/documents/attach

Firm memberPermission: case:writeMCP tool: attachDocument

Attach an already-uploaded document (documentId) to a DRAFT notification, as kind auto_admisorio | demanda | anexo | subsanacion | providencia | otro. The file is copied to immutable evidence storage and its SHA-256 recorded; total attachments must stay under 20 MB. Nothing is sent.

Parameters of attachDocument
NameInTypeRequired
documentIdBodystring (uuid)Yes
kindBody"auto_admisorio" | "demanda" | "anexo" | "subsanacion" | "providencia" | "otro"Yes
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/documents/attach' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "documentId": "<documentId>",
  "kind": "auto_admisorio",
  "notificationId": "<notificationId>",
  "orgId": "<orgId>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/documents/attach', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "documentId": "<documentId>",
    "kind": "auto_admisorio",
    "notificationId": "<notificationId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": -9007199254740991,
  "filename": "<filename>",
  "id": "<id>",
  "kind": "auto_admisorio",
  "mime": "<mime>",
  "position": -9007199254740991,
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

updateDraft

POST/api/drafts/update

Firm memberPermission: case:writeMCP tool: updateDraft

Rewrite a DRAFT art. 8 (Ley 2213) notification: pass orgId, notificationId, template "art8-personal", the providencia name and its date (YYYY-MM-DD), and optionally terminoDias and mensaje — omitting them removes them. The subject and body are recomposed from the template; the deemed-done and term-start sentences always stay. Refused once the notification was sent.

Parameters of updateDraft
NameInTypeRequired
mensajeBodystring 1–5000No
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
providenciaBodystring 1–200Yes
providenciaFechaBodystringYes
templateBody"art8-personal"Yes
terminoDiasBodyinteger 1–365No
curl
curl -X POST 'https://www.notificado.co/api/drafts/update' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "notificationId": "<notificationId>",
  "orgId": "<orgId>",
  "providencia": "<providencia>",
  "providenciaFecha": "<providenciaFecha>",
  "template": "art8-personal"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/drafts/update', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "notificationId": "<notificationId>",
    "orgId": "<orgId>",
    "providencia": "<providencia>",
    "providenciaFecha": "<providenciaFecha>",
    "template": "art8-personal"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "createdAt": "2026-09-25T15:00:00Z",
  "emlSha256": "<emlSha256>",
  "frozenAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "sentAt": "2026-09-25T15:00:00Z",
  "status": "draft",
  "subject": "<subject>",
  "tier": "standard"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

createNotification

POST/api/notifications/create

Firm memberPermission: case:writeMCP tool: createNotification

Create a DRAFT art. 8 (Ley 2213) personal notification on a case: pass orgId, caseId, template "art8-personal", the providencia name and its date (YYYY-MM-DD). The body already states when the notification is deemed done and when terms start. Nothing is sent and no credit is used; add recipients (a lawyer swears each address in the panel) and attach documents next.

Parameters of createNotification
NameInTypeRequired
caseIdBodystring (uuid)Yes
mensajeBodystring 1–5000No
orgIdBodystring (uuid)Yes
providenciaBodystring 1–200Yes
providenciaFechaBodystringYes
templateBody"art8-personal"Yes
terminoDiasBodyinteger 1–365No
curl
curl -X POST 'https://www.notificado.co/api/notifications/create' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "caseId": "<caseId>",
  "orgId": "<orgId>",
  "providencia": "<providencia>",
  "providenciaFecha": "<providenciaFecha>",
  "template": "art8-personal"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/notifications/create', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "caseId": "<caseId>",
    "orgId": "<orgId>",
    "providencia": "<providencia>",
    "providenciaFecha": "<providenciaFecha>",
    "template": "art8-personal"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "createdAt": "2026-09-25T15:00:00Z",
  "emlSha256": "<emlSha256>",
  "frozenAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "sentAt": "2026-09-25T15:00:00Z",
  "status": "draft",
  "subject": "<subject>",
  "tier": "standard"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

addParty

POST/api/parties/add

Firm memberPermission: case:writeMCP tool: addParty

Add a party to a case of the caller's firm: caseId, role demandante | demandado | apoderado | otro, the name as written in the demanda, and idNumber (cédula or NIT with its check digit) when known. A party is NOT a recipient: who gets notified, at which address, is sworn by the lawyer in the panel. Refused X_CASE_LOCKED once a notification of the case left draft.

Parameters of addParty
NameInTypeRequired
caseIdBodystring (uuid)Yes
idNumberBodystring 1–40No
nameBodystring 1–300Yes
roleBody"demandante" | "demandado" | "apoderado" | "otro"Yes
curl
curl -X POST 'https://www.notificado.co/api/parties/add' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"caseId":"<caseId>","name":"<name>","role":"demandante"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/parties/add', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "caseId": "<caseId>",
    "name": "<name>",
    "role": "demandante"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "id": "<id>",
  "idNumber": "<idNumber>",
  "name": "<name>",
  "role": "demandante"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

removeRecipient

POST/api/recipients/remove

Firm memberPermission: case:write

removeRecipient

Parameters of removeRecipient
NameInTypeRequired
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
recipientIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/recipients/remove' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "notificationId": "<notificationId>",
  "orgId": "<orgId>",
  "recipientId": "<recipientId>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/recipients/remove', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "notificationId": "<notificationId>",
    "orgId": "<orgId>",
    "recipientId": "<recipientId>"
  }),
});
const result = await response.json();
Example response
200
{
  "email": "<email>",
  "id": "<id>",
  "name": "<name>",
  "notificationId": "<notificationId>",
  "status": "queued"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Notifications

bounceAlerts

GET/_x/query/bounce-alerts

Firm memberPermission: notification:readMCP tool: bounceAlerts

Recipients whose notification could NOT be delivered (status bounced: the mail server refused it for good) or who marked it as unwanted (complained), newest first, with the case radicado. Without notificationId: only those not yet re-issued to another address. With notificationId: that notification's failed recipients, `switched: true` when already re-issued. Next steps for a bounce: verify the address, re-issue to another sworn address in the panel (switchChannel), or notify by physical means. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

listPendingSends

GET/_x/query/list-pending-sends

Firm memberPermission: and(notification:send, notification:send)

listPendingSends

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

memorialReadiness

GET/_x/query/memorial-readiness

Firm memberPermission: memorial:readMCP tool: memorialReadiness

Whether a memorial can be generated now for one notification in your organization. One row: ready, and when not ready the reason — "bounce" (a recipient bounced: NOT notified; re-issue to another address first), "not-delivered" (a recipient server has not accepted the message yet), "constancia-pending" or "term-pending" (still being produced, retry in a minute) — with the X_ code createMemorial would refuse with. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

notificationDetail

GET/_x/query/notification-detail

Firm memberPermission: notification:readMCP tool: notificationDetail

One notification by id: status, recipients with delivery status and how each address was obtained, attachments with SHA-256, and the evidence timeline (message.frozen, transport.sent, mail.delivery, bounces, downloads, acknowledgements) in chain order with UTC times. Opens are marked indicio (never proof of reading). Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

notificationList

GET/_x/query/notification-list

Firm memberPermission: notification:readMCP tool: notificationList

List the org’s notifications, newest first: id, case, status (draft | freezing | frozen | sending | sent | failed), subject, the frozen .eml SHA-256 and UTC timestamps. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

notificationMemorials

GET/_x/query/notification-memorials

Firm memberPermission: memorial:readMCP tool: notificationMemorials

The memorials generated for one notification in your organization, newest first: id, createdAt, and the SHA-256 and size of the DOCX and the PDF, plus factsSha256 (the hash of the facts the memorial cites). Poll it after createMemorial until the new memorialId appears (seconds), then fetch the files with downloadMemorial. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

sendConfirmationDetail

GET/_x/query/send-confirmation-detail

Firm memberPermission: notification:read

sendConfirmationDetail

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

switchChannel

POST/api/channels/switch

Firm memberPermission: notification:send

switchChannel

Parameters of switchChannel
NameInTypeRequired
emailBodystring 1–320Yes
evidenceDocumentIdsBodyarray of string 1–64No
juramentoBodyboolean | string 0–8No
nameBodystring 0–300No
notificationIdBodystring 1–64No
orgIdBodystring 1–64Yes
overrideReasonBodystring 0–2000 | nullNo
recipientIdBodystring 1–64Yes
sourceBodystring 1–64Yes
sourceTextBodystring 1–2000Yes
curl
curl -X POST 'https://www.notificado.co/api/channels/switch' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "email": "<email>",
  "orgId": "<orgId>",
  "recipientId": "<recipientId>",
  "source": "<source>",
  "sourceText": "<sourceText>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/channels/switch', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "email": "<email>",
    "orgId": "<orgId>",
    "recipientId": "<recipientId>",
    "source": "<source>",
    "sourceText": "<sourceText>"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "createdAt": "2026-09-25T15:00:00Z",
  "emlSha256": "<emlSha256>",
  "frozenAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "sentAt": "2026-09-25T15:00:00Z",
  "status": "draft",
  "subject": "<subject>",
  "tier": "standard"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

createMemorial

POST/api/memorials/create

Firm memberPermission: memorial:writeMCP tool: createMemorial

Generates the memorial (DOCX + PDF draft, in Spanish) that informs the juzgado that personal notification under art. 8 Ley 2213 de 2022 was practised for one notification in your organization: radicado, juzgado, parties, each recipient with sent/delivered/acknowledged times in America/Bogota, the sworn forma de obtención, the constancia verify code and URL, the computed term dates with their disclaimer and inputsSha256, and the annexes with SHA-256. Returns the memorialId and the render job handle; download the files with downloadMemorial once notificationMemorials lists it (seconds). It is a DRAFT marked [LAWYER REVIEW]: a lawyer must review, sign and file it — nothing is sent to the court. Refused with X_MEMORIAL_BLOCKED_BOUNCE while any recipient bounced, X_MEMORIAL_NOT_DELIVERED before delivery, X_MEMORIAL_CONSTANCIA_PENDING / X_MEMORIAL_TERM_PENDING while those are still being produced.

Parameters of createMemorial
NameInTypeRequired
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/memorials/create' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"notificationId":"<notificationId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/memorials/create', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "notificationId": "<notificationId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "charge": "free",
  "jobId": "<jobId>",
  "memorialId": "<memorialId>",
  "templateId": "<templateId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

downloadMemorial

POST/api/memorials/download

Firm memberPermission: memorial:readMCP tool: downloadMemorial

Returns the bytes (base64, with filename, content type and SHA-256) of one generated memorial in your organization, as "docx" (editable, for the lawyer to review and sign) or "pdf" (with the constancia verification QR). The SHA-256 is re-checked against the memorial record before the bytes are served, and every download is recorded in the audit log. Fails X_MEMORIAL_NOT_FOUND for an unknown id or one whose render job has not finished.

Parameters of downloadMemorial
NameInTypeRequired
formatBody"docx" | "pdf"Yes
memorialIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/memorials/download' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"format":"docx","memorialId":"<memorialId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/memorials/download', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "format": "docx",
    "memorialId": "<memorialId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "filename": "<filename>",
  "format": "docx",
  "memorialId": "<memorialId>",
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

sendNotification

POST/api/notifications/send

Firm memberPermission: notification:sendMCP tool: sendNotification

REQUEST the send of a draft notification — REQUIRES HUMAN CONFIRMATION. Over MCP this never sends: it checks the draft is ready (recipients sworn by the lawyer in the panel, at least one attachment, under 20 MB) and returns { status: "awaiting_confirmation", confirmUrl, expiresAt }; hand confirmUrl to the lawyer, who confirms in the panel within 24 hours — only then is one credit per recipient consumed and the exact message frozen, timestamped and emailed. Call it once, with confirm: true, only after showing the lawyer the recipients and attachments. Do NOT call it to test, and do not retry after awaiting_confirmation. Requires an approved lawyer KYC (X_KYC_REQUIRED otherwise).

Parameters of sendNotification
NameInTypeRequired
confirmBodytrueYes
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/notifications/send' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"confirm":true,"notificationId":"<notificationId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/notifications/send', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "confirm": true,
    "notificationId": "<notificationId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "createdAt": "2026-09-25T15:00:00Z",
  "emlSha256": "<emlSha256>",
  "frozenAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "sentAt": "2026-09-25T15:00:00Z",
  "status": "draft",
  "subject": "<subject>",
  "tier": "standard"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

addRecipient

POST/api/recipients/add

Firm memberPermission: notification:send

addRecipient

Parameters of addRecipient
NameInTypeRequired
emailBodystring (email)Yes
evidenceDocumentIdsBodyarray of string (uuid)Yes
juramentoBodybooleanYes
nameBodystring 1–300Yes
notificationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
overrideReasonBodystring 1–2000 | nullNo
sourceBody"comunicaciones_previas" | "camara_de_comercio" | "rut" | "contrato" | "web_oficial" | "otro"Yes
sourceTextBodystring 1–2000Yes
curl
curl -X POST 'https://www.notificado.co/api/recipients/add' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "email": "<email>",
  "evidenceDocumentIds": [],
  "juramento": true,
  "name": "<name>",
  "notificationId": "<notificationId>",
  "orgId": "<orgId>",
  "source": "comunicaciones_previas",
  "sourceText": "<sourceText>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/recipients/add', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "email": "<email>",
    "evidenceDocumentIds": [],
    "juramento": true,
    "name": "<name>",
    "notificationId": "<notificationId>",
    "orgId": "<orgId>",
    "source": "comunicaciones_previas",
    "sourceText": "<sourceText>"
  }),
});
const result = await response.json();
Example response
200
{
  "email": "<email>",
  "id": "<id>",
  "name": "<name>",
  "notificationId": "<notificationId>",
  "status": "queued"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmSend

POST/api/sends/confirm

Firm memberPermission: and(notification:send, notification:send)

confirmSend

Parameters of confirmSend
NameInTypeRequired
confirmationIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
returnToBodystring 1–2048No
curl
curl -X POST 'https://www.notificado.co/api/sends/confirm' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"confirmationId":"<confirmationId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/sends/confirm', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "confirmationId": "<confirmationId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "caseId": "<caseId>",
  "createdAt": "2026-09-25T15:00:00Z",
  "emlSha256": "<emlSha256>",
  "frozenAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "sentAt": "2026-09-25T15:00:00Z",
  "status": "draft",
  "subject": "<subject>",
  "tier": "standard"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Evidence

verifyChain

GET/_x/query/verify-chain

Firm memberPermission: evidence:verifyMCP tool: verifyChain

Verify the hash-chained evidence log between two sequence numbers (at most 100000 events) and name the first broken event. Staff only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

runChainVerification

POST/api/chain-verifications/run

Firm memberPermission: evidence:verifyMCP tool: runChainVerification

Staff only. Verify the hash-chained evidence log between two sequence numbers. Up to 50000 events are verified in the call and answer { ok, checked, firstBroken? }; a longer range (up to 10000000) is queued and answers { enqueued: true, jobId }. deep also re-hashes the raw provider objects. Read-only; every call is audited.

Parameters of runChainVerification
NameInTypeRequired
confirmTokenBodystring 1–200No
deepBodybooleanNo
fromSeqBodyinteger 1–9007199254740991Yes
toSeqBodyinteger 1–9007199254740991Yes
curl
curl -X POST 'https://www.notificado.co/api/chain-verifications/run' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"fromSeq":1,"toSeq":1}'
TypeScript
const response = await fetch('https://www.notificado.co/api/chain-verifications/run', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "fromSeq": 1,
    "toSeq": 1
  }),
});
const result = await response.json();
Example response
200
{
  "checked": -9007199254740991,
  "deep": true,
  "firstBroken": {
    "id": "<id>",
    "reason": "<reason>",
    "seq": -9007199254740991
  },
  "fromSeq": -9007199254740991,
  "ok": true,
  "toSeq": -9007199254740991
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

reissueConstancia

POST/api/constancias/reissue

Firm memberPermission: evidence:read

reissueConstancia

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

downloadEvidence

POST/api/evidences/download

Firm memberPermission: evidence:readMCP tool: downloadEvidence

Returns the bytes (base64, with filename, content type and SHA-256) of the signed constancia PDF (kind "constancia") or the offline-verifiable evidence zip (kind "zip") of one notification in your organization; newest version unless "version" is given. Every call is recorded in the audit log and as an evidence.viewed event. Fails X_CONSTANCIA_NOT_FOUND before the first constancia is issued and X_EVIDENCE_ZIP_NOT_READY while the zip is still being built.

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Deadlines

listDeadlines

GET/_x/query/list-deadlines

Firm memberPermission: deadline:readMCP tool: listDeadlines

The caller's firm's deadlines (términos) under Ley 2213 art. 8, one row per notification × recipient: surtidaOn (envío + 2 días hábiles), termStartsOn (next día hábil) and termEndsOn (vencimiento, after termDays días hábiles), all YYYY-MM-DD in America/Bogota, skipping weekends, festivos, vacancia judicial and court closures. status 'blocked_bounce' means the recipient bounced: NOT notified, no dates. Filter by caseId, and by vencimiento day with from/to (YYYY-MM-DD, inclusive). Soonest vencimiento first. The dates are an ESTIMATE — always tell the user the judge decides (disclaimerKey), and cite calendarVersion + inputsSha256 when quoting one. Read-only.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

setCourtClosure

POST/api/court-closures/set

Firm memberPermission: deadline:write

setCourtClosure

Parameters of setCourtClosure
NameInTypeRequired
courtIdBodystringNo
endsOnBodystringYes
globalBodybooleanNo
kindBody"cierre_extraordinario" | "vacancia_colectiva" | "semana_santa"No
sourceUrlBodystring (uri) ≤ 2048No
startsOnBodystringYes
curl
curl -X POST 'https://www.notificado.co/api/court-closures/set' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"endsOn":"<endsOn>","startsOn":"<startsOn>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/court-closures/set', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "endsOn": "<endsOn>",
    "startsOn": "<startsOn>"
  }),
});
const result = await response.json();
Example response
200
{
  "courtId": "<courtId>",
  "endsOn": "<endsOn>",
  "global": true,
  "id": "<id>",
  "kind": "<kind>",
  "recomputing": -9007199254740991,
  "startsOn": "<startsOn>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Credits, payments and invoicing

checkoutTerms

GET/_x/query/checkout-terms

Firm memberPermission: billing:purchase

checkoutTerms

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

creditsBalance

GET/_x/query/credits-balance

Firm memberPermission: billing:readMCP tool: creditsBalance

Credits balance of the caller's org: `balance` is how many recipients can still be notified (one credit per recipient, consumed on send), and `nextExpiryAt`/`nextExpiryCredits` say when the soonest batch of credits expires (UTC). Read before sending to more recipients than the balance covers.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

ledgerList

GET/_x/query/ledger-list

Firm memberPermission: billing:read

ledgerList

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

listMyInvoices

GET/_x/query/list-my-invoices

Firm memberPermission: invoicing:readMCP tool: listMyInvoices

Lists your organization's DIAN electronic invoices, newest first: status (queued, issued, rejected), DIAN number, CUFE, net, discount, IVA and gross amounts in COP minor units (centavos), due date for credit invoices, and whether the PDF / XML is ready for downloadInvoice.

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

listMyPayments

GET/_x/query/list-my-payments

Firm memberPermission: payment:read

listMyPayments

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

myBillingProfile

GET/_x/query/my-billing-profile

Firm memberPermission: payment:read

myBillingProfile

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

mySubscription

GET/_x/query/my-subscription

Firm memberPermission: payment:read

mySubscription

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

nequiSourceStatus

GET/_x/query/nequi-source-status

Firm memberPermission: payment:read

nequiSourceStatus

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

packOffers

GET/_x/query/pack-offers

Firm memberPermission: payment:read

packOffers

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

paymentStatus

GET/_x/query/payment-status

Firm memberPermission: payment:read

paymentStatus

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

planOffers

GET/_x/query/plan-offers

Firm memberPermission: payment:read

planOffers

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

requestApproval

POST/api/approvals/request

Firm memberPermission: billing:grantMCP tool: requestApproval

Staff only (billing:grant). Files a four-eyes request to grant (credits.grant, needs invoiceRef) or adjust (credits.adjust) more than 100 credits for a customer org. A different staff member must approve it in the console; it then executes by itself. Returns the request.

Parameters of requestApproval
NameInTypeRequired
creditsBodyinteger -100000–100000Yes
invoiceRefBodystring 1–120No
kindBody"credits.grant" | "credits.adjust"Yes
orgIdBodystring (uuid)Yes
packageCodeBodystring 1–40No
reasonBodystring 1–1000Yes
validDaysBodyinteger 1–3650No
curl
curl -X POST 'https://www.notificado.co/api/approvals/request' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "credits": -100000,
  "kind": "credits.grant",
  "orgId": "<orgId>",
  "reason": "<reason>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/approvals/request', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "credits": -100000,
    "kind": "credits.grant",
    "orgId": "<orgId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "amount": {
    "currency": "<currency>",
    "minor": -9007199254740991
  },
  "credits": -9007199254740991,
  "decidedAt": "2026-09-25T15:00:00Z",
  "decidedBy": "<decidedBy>",
  "decisionReason": "<decisionReason>",
  "executedRef": "<executedRef>",
  "expiresAt": "2026-09-25T15:00:00Z",
  "failureReason": "<failureReason>",
  "id": "<id>",
  "kind": "<kind>",
  "payload": {},
  "payloadSha256": "<payloadSha256>",
  "reason": "<reason>",
  "requestedAt": "2026-09-25T15:00:00Z",
  "requestedBy": "<requestedBy>",
  "status": "<status>",
  "subjectOrgId": "<subjectOrgId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

saveBillingProfile

POST/api/billing-profiles/save

Firm memberPermission: billing:purchase

saveBillingProfile

Parameters of saveBillingProfile
NameInTypeRequired
addressBodystring 1–200Yes
cityCodeBodystring 5–5Yes
docNumberBodystring 3–20Yes
docTypeBody"CC" | "NIT" | "CE" | "PP"Yes
dvBody"" | string 1–1 | nullYes
emailBodystring (email) ≤ 254Yes
fiscalResponsibilitiesBodyarray of string 1–12 | "" | string 1–200Yes
legalNameBodystring 1–200Yes
orgIdBodystring (uuid)Yes
returnToBodystring 1–240No
taxRegimeBody"responsable_iva" | "no_responsable_iva" | "simple"Yes
curl
curl -X POST 'https://www.notificado.co/api/billing-profiles/save' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "address": "<address>",
  "cityCode": "<cityCode>",
  "docNumber": "<docNumber>",
  "docType": "CC",
  "dv": "",
  "email": "<email>",
  "fiscalResponsibilities": [],
  "legalName": "<legalName>",
  "orgId": "<orgId>",
  "taxRegime": "responsable_iva"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/billing-profiles/save', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "address": "<address>",
    "cityCode": "<cityCode>",
    "docNumber": "<docNumber>",
    "docType": "CC",
    "dv": "",
    "email": "<email>",
    "fiscalResponsibilities": [],
    "legalName": "<legalName>",
    "orgId": "<orgId>",
    "taxRegime": "responsable_iva"
  }),
});
const result = await response.json();
Example response
200
{
  "address": "<address>",
  "cityCode": "<cityCode>",
  "docNumber": "<docNumber>",
  "docType": "CC",
  "dv": "<dv>",
  "email": "<email>",
  "fiscalResponsibilities": [
    "<fiscalResponsibilities>"
  ],
  "legalName": "<legalName>",
  "taxRegime": "responsable_iva",
  "updatedAt": "2026-09-25T15:00:00Z"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

previewCoupon

POST/api/coupons/preview

Firm memberPermission: billing:read

previewCoupon

Parameters of previewCoupon
NameInTypeRequired
codeBodystring 1–40Yes
intervalBody"month" | "year"No
kindBody"pack" | "plan"Yes
orgIdBodystring (uuid)Yes
subjectCodeBodystring 1–40Yes
curl
curl -X POST 'https://www.notificado.co/api/coupons/preview' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "code": "<code>",
  "kind": "pack",
  "orgId": "<orgId>",
  "subjectCode": "<subjectCode>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/coupons/preview', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "code": "<code>",
    "kind": "pack",
    "orgId": "<orgId>",
    "subjectCode": "<subjectCode>"
  }),
});
const result = await response.json();
Example response
200
{
  "coupon": {
    "amountOff": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "appliesTo": "pack",
    "code": "<code>",
    "cycles": -9007199254740991,
    "duration": "once",
    "kind": "percent",
    "percentBps": -9007199254740991,
    "validTo": "2026-09-25T15:00:00Z"
  },
  "discount": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  },
  "gross": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  },
  "iva": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  },
  "net": {
    "currency": "<currency>",
    "minor": -9007199254740991,
    "scale": 0
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adjustCredits

POST/api/credits/adjust

Firm memberPermission: billing:grant

adjustCredits

Parameters of adjustCredits
NameInTypeRequired
deltaBodyinteger -100000–100000Yes
orgIdBodystring (uuid)Yes
reasonBodystring 1–120Yes
curl
curl -X POST 'https://www.notificado.co/api/credits/adjust' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"delta":-100000,"orgId":"<orgId>","reason":"<reason>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/credits/adjust', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "delta": -100000,
    "orgId": "<orgId>",
    "reason": "<reason>"
  }),
});
const result = await response.json();
Example response
200
{
  "createdAt": "2026-09-25T15:00:00Z",
  "delta": -9007199254740991,
  "expiresAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "kind": "<kind>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

grantCredits

POST/api/credits/grant

Firm memberPermission: billing:grant

grantCredits

Parameters of grantCredits
NameInTypeRequired
creditsBodyinteger -9007199254740991–9007199254740991 | string 0–12Yes
invoiceRefBodystring 1–120Yes
orgIdBodystring 1–64Yes
packageCodeBodystring 0–40No
validDaysBodyinteger -9007199254740991–9007199254740991 | string 0–12No
curl
curl -X POST 'https://www.notificado.co/api/credits/grant' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "credits": -9007199254740991,
  "invoiceRef": "<invoiceRef>",
  "orgId": "<orgId>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/credits/grant', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "credits": -9007199254740991,
    "invoiceRef": "<invoiceRef>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "createdAt": "2026-09-25T15:00:00Z",
  "delta": -9007199254740991,
  "expiresAt": "2026-09-25T15:00:00Z",
  "id": "<id>",
  "kind": "<kind>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

payCycle

POST/api/cycles/pay

Firm memberPermission: billing:purchase

payCycle

Parameters of payCycle
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
cycleIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
overageBodybooleanNo
curl
curl -X POST 'https://www.notificado.co/api/cycles/pay' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"cycleId":"<cycleId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/cycles/pay', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "cycleId": "<cycleId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "checkout": {
    "action": "<action>",
    "fields": {},
    "method": "GET"
  },
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  }
}

Errors

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

downloadInvoice

POST/api/invoices/download

Firm memberPermission: invoicing:readMCP tool: downloadInvoice

Returns the bytes (base64, with filename, content type and SHA-256) of the PDF or XML of one DIAN electronic invoice of your organization (format "pdf" or "xml"), or of one of its credit notes when creditNoteId is given. Every call is recorded in the audit log. Fails X_INVOICE_FILE_NOT_READY while the document is not issued yet (listMyInvoices shows its status).

Parameters of downloadInvoice
NameInTypeRequired
creditNoteIdBodystring (uuid)No
formatBody"pdf" | "xml"Yes
invoiceIdBodystring (uuid)Yes
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/invoices/download' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"format":"pdf","invoiceId":"<invoiceId>","orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/invoices/download', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "format": "pdf",
    "invoiceId": "<invoiceId>",
    "orgId": "<orgId>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "filename": "<filename>",
  "format": "pdf",
  "number": "<number>",
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

startPackCheckout

POST/api/pack-checkouts/start

Firm memberPermission: billing:purchase

startPackCheckout

Parameters of startPackCheckout
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
billingProfileBodyobjectNo
captchaTokenBodystring 0–4096No
cf-turnstile-responseBodystring 0–4096No
couponCodeBodystring 1–40No
h-captcha-responseBodystring 0–4096No
methodBodyobject | object | object | objectNo
orgIdBodystring (uuid)Yes
packCodeBodystring 1–40Yes
payerNameBodystring 1–200No
payerPhoneBodystring 10–15No
termsBodyobjectNo
curl
curl -X POST 'https://www.notificado.co/api/pack-checkouts/start' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","packCode":"<packCode>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/pack-checkouts/start', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "packCode": "<packCode>"
  }),
});
const result = await response.json();
Example response
200
{
  "asyncPaymentUrl": "<asyncPaymentUrl>",
  "checkout": {
    "action": "<action>",
    "fields": {},
    "method": "GET"
  },
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  },
  "transactionId": "<transactionId>"
}

Errors

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

confirmPaymentReturn

POST/api/payment-returns/confirm

Firm memberPermission: billing:purchase

confirmPaymentReturn

Parameters of confirmPaymentReturn
NameInTypeRequired
orgIdBodystring (uuid)Yes
transactionIdBodystring 1–64Yes
curl
curl -X POST 'https://www.notificado.co/api/payment-returns/confirm' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","transactionId":"<transactionId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/payment-returns/confirm', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "transactionId": "<transactionId>"
  }),
});
const result = await response.json();
Example response
200
{
  "asyncPaymentUrl": "<asyncPaymentUrl>",
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

registerPaymentSource

POST/api/payment-sources/register

Firm memberPermission: billing:purchase

registerPaymentSource

Parameters of registerPaymentSource
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
orgIdBodystring (uuid)Yes
sourceBodyobject | objectYes
termsBodyobjectYes
useForSubscriptionBodybooleanNo
curl
curl -X POST 'https://www.notificado.co/api/payment-sources/register' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "orgId": "<orgId>",
  "source": {
    "token": "<token>",
    "type": "CARD"
  },
  "terms": {
    "acceptanceToken": "<acceptanceToken>",
    "personalDataToken": "<personalDataToken>"
  }
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/payment-sources/register', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "source": {
      "token": "<token>",
      "type": "CARD"
    },
    "terms": {
      "acceptanceToken": "<acceptanceToken>",
      "personalDataToken": "<personalDataToken>"
    }
  }),
});
const result = await response.json();
Example response
200
{
  "id": "<id>",
  "label": "<label>",
  "status": "<status>",
  "type": "<type>"
}

Errors

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

refreshPayment

POST/api/payments/refresh

Firm memberPermission: billing:purchase

refreshPayment

Parameters of refreshPayment
NameInTypeRequired
orgIdBodystring (uuid)Yes
paymentIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/payments/refresh' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","paymentId":"<paymentId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/payments/refresh', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "paymentId": "<paymentId>"
  }),
});
const result = await response.json();
Example response
200
{
  "asyncPaymentUrl": "<asyncPaymentUrl>",
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  }
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

changePlan

POST/api/plans/change

Firm memberPermission: billing:purchase

changePlan

Parameters of changePlan
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
intervalBody"month" | "year"No
orgIdBodystring (uuid)Yes
planCodeBodystring 1–40Yes
curl
curl -X POST 'https://www.notificado.co/api/plans/change' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>","planCode":"<planCode>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/plans/change', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "orgId": "<orgId>",
    "planCode": "<planCode>"
  }),
});
const result = await response.json();
Example response
200
{
  "change": "upgraded",
  "checkout": {
    "action": "<action>",
    "fields": {},
    "method": "GET"
  },
  "effectiveAt": "2026-09-25T15:00:00Z",
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  }
}

Errors

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

subscribe

POST/api/subscribes/invoke

Firm memberPermission: billing:purchase

subscribe

Parameters of subscribe
NameInTypeRequired
Idempotency-KeyQuerystring ≤ 255Replays the first response for a repeated key.No
billingProfileBodyobjectNo
collectionBody"auto" | "link"Yes
couponCodeBodystring 1–40No
intervalBody"month" | "year"Yes
orgIdBodystring (uuid)Yes
paymentSourceIdBodystring (uuid)No
planCodeBodystring 1–40Yes
curl
curl -X POST 'https://www.notificado.co/api/subscribes/invoke' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{
  "collection": "auto",
  "interval": "month",
  "orgId": "<orgId>",
  "planCode": "<planCode>"
}'
TypeScript
const response = await fetch('https://www.notificado.co/api/subscribes/invoke', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "collection": "auto",
    "interval": "month",
    "orgId": "<orgId>",
    "planCode": "<planCode>"
  }),
});
const result = await response.json();
Example response
200
{
  "checkout": {
    "action": "<action>",
    "fields": {},
    "method": "GET"
  },
  "cycle": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "attempts": -9007199254740991,
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "nextAttemptAt": "2026-09-25T15:00:00Z",
    "periodEnd": "2026-09-25T15:00:00Z",
    "periodStart": "2026-09-25T15:00:00Z",
    "status": "due",
    "subscriptionId": "<subscriptionId>"
  },
  "payment": {
    "amountGross": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountIva": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "amountNet": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "approvedAt": "2026-09-25T15:00:00Z",
    "createdAt": "2026-09-25T15:00:00Z",
    "discount": {
      "currency": "<currency>",
      "minor": -9007199254740991,
      "scale": 0
    },
    "id": "<id>",
    "method": "CARD",
    "purpose": "pack",
    "reference": "<reference>",
    "status": "created",
    "statusAt": "2026-09-25T15:00:00Z",
    "subjectId": "<subjectId>"
  },
  "subscription": {
    "cancelAtPeriodEnd": true,
    "collection": "auto",
    "currentPeriodEnd": "2026-09-25T15:00:00Z",
    "currentPeriodStart": "2026-09-25T15:00:00Z",
    "endedAt": "2026-09-25T15:00:00Z",
    "freeCyclesPending": -9007199254740991,
    "id": "<id>",
    "interval": "month",
    "planId": "<planId>",
    "status": "trialing"
  }
}

Errors

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

cancelSubscription

POST/api/subscriptions/cancel

Firm memberPermission: billing:purchase

cancelSubscription

Parameters of cancelSubscription
NameInTypeRequired
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/subscriptions/cancel' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/subscriptions/cancel', {
  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
{
  "cancelAtPeriodEnd": true,
  "collection": "auto",
  "currentPeriodEnd": "2026-09-25T15:00:00Z",
  "currentPeriodStart": "2026-09-25T15:00:00Z",
  "endedAt": "2026-09-25T15:00:00Z",
  "freeCyclesPending": -9007199254740991,
  "id": "<id>",
  "interval": "month",
  "planId": "<planId>",
  "status": "trialing"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

resumeSubscription

POST/api/subscriptions/resume

Firm memberPermission: billing:purchase

resumeSubscription

Parameters of resumeSubscription
NameInTypeRequired
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/subscriptions/resume' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/subscriptions/resume', {
  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
{
  "cancelAtPeriodEnd": true,
  "collection": "auto",
  "currentPeriodEnd": "2026-09-25T15:00:00Z",
  "currentPeriodStart": "2026-09-25T15:00:00Z",
  "endedAt": "2026-09-25T15:00:00Z",
  "freeCyclesPending": -9007199254740991,
  "id": "<id>",
  "interval": "month",
  "planId": "<planId>",
  "status": "trialing"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Agent tokens

issueAgentToken

POST/api/agent-tokens/issue

Firm memberPermission: api-access:write

issueAgentToken

Parameters of issueAgentToken
NameInTypeRequired
nameBodystring 1–100Yes
orgIdBodystring (uuid)Yes
scopesBodyarray of string 1–40give between 1 and 10 scopesYes
ttlDaysBody30 | 90 | 365 | nullYes
curl
curl -X POST 'https://www.notificado.co/api/agent-tokens/issue' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"name":"<name>","orgId":"<orgId>","scopes":[],"ttlDays":30}'
TypeScript
const response = await fetch('https://www.notificado.co/api/agent-tokens/issue', {
  method: 'POST',
  headers: { 'content-type': 'application/json', origin: 'https://www.notificado.co', cookie: sessionCookie },
  body: JSON.stringify({
    "name": "<name>",
    "orgId": "<orgId>",
    "scopes": [],
    "ttlDays": 30
  }),
});
const result = await response.json();
Example response
200
{
  "summary": {
    "createdAt": "2026-09-25T15:00:00Z",
    "createdAtBogota": "<createdAtBogota>",
    "expiresAt": "2026-09-25T15:00:00Z",
    "expiresAtBogota": "<expiresAtBogota>",
    "id": "<id>",
    "lastUsedAt": "2026-09-25T15:00:00Z",
    "lastUsedAtBogota": "<lastUsedAtBogota>",
    "name": "<name>",
    "prefix": "<prefix>",
    "revokedAt": "2026-09-25T15:00:00Z",
    "revokedAtBogota": "<revokedAtBogota>",
    "scopes": [
      "cases:read"
    ],
    "status": "active",
    "userId": "<userId>"
  },
  "token": "<token>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listAgentTokens

POST/api/agent-tokens/list

Firm memberPermission: api-access:read

listAgentTokens

Parameters of listAgentTokens
NameInTypeRequired
orgIdBodystring (uuid)Yes
curl
curl -X POST 'https://www.notificado.co/api/agent-tokens/list' \
  -b cookies.txt \
  -H 'origin: https://www.notificado.co' \
  -H 'content-type: application/json' \
  -d '{"orgId":"<orgId>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/agent-tokens/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
{
  "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>",
      "prefix": "<prefix>",
      "revokedAt": "2026-09-25T15:00:00Z",
      "revokedAtBogota": "<revokedAtBogota>",
      "scopes": [
        "cases:read"
      ],
      "status": "active",
      "userId": "<userId>"
    }
  ]
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeAgentToken

POST/api/agent-tokens/revoke

Firm memberPermission: api-access:write

revokeAgentToken

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Public and webhooks

recipientPage

GET/_x/query/recipient-page

No sessionPermission: public

recipientPage

Parameters of recipientPage
NameInTypeRequired
recipientTokenQuerystring 1–64Yes
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/recipient-page?recipientToken=<recipientToken>'
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/recipient-page?recipientToken=<recipientToken>');
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

verifyConstancia

GET/_x/query/verify-constancia

No sessionPermission: publicMCP tool: verifyConstancia

Public check of a Notificado constancia: pass the verification code printed under its QR ("code") or the SHA-256 of the PDF file ("pdfSha256"). Returns one row: authentic, issuedAt (UTC and Bogotá), delivery status, the signed PDF's SHA-256, version, latestVersion and superseded. Never returns message content or recipient data; an unknown code or hash returns authentic=false with every other field null.

Parameters of verifyConstancia
NameInTypeRequired
codeQuerystring 1–32No
pdfSha256QuerystringNo
_firstQueryinteger 1–10000page size; present, the response is the page envelope rather than the bare rows (1 to 10000)No
_afterQuerystringthe endCursor a previous page answered; needs _firstNo
curl
curl 'https://www.notificado.co/_x/query/verify-constancia'
TypeScript
const response = await fetch('https://www.notificado.co/_x/query/verify-constancia');
const result = await response.json();
Example response
200
[
  null
]

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

recordDownload

POST/api/downloads/record

No sessionPermission: public

recordDownload

Parameters of recordDownload
NameInTypeRequired
linkTokenBodystringYes
recipientTokenBodystringYes
curl
curl -X POST 'https://www.notificado.co/api/downloads/record' \
  -H 'content-type: application/json' \
  -d '{"linkToken":"<linkToken>","recipientToken":"<recipientToken>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/downloads/record', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "linkToken": "<linkToken>",
    "recipientToken": "<recipientToken>"
  }),
});
const result = await response.json();
Example response
200
{
  "bytes": 0,
  "contentBase64": "<contentBase64>",
  "contentType": "<contentType>",
  "eventId": "<eventId>",
  "filename": "<filename>",
  "sha256": "<sha256>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

health

POST/api/healths/invoke

No sessionPermission: publicMCP tool: health

Readiness of this process

curl
curl -X POST 'https://www.notificado.co/api/healths/invoke' \
  -H 'content-type: application/json' \
  -d '{}'
TypeScript
const response = await fetch('https://www.notificado.co/api/healths/invoke', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({}),
});
const result = await response.json();
Example response
200
{
  "ok": true,
  "role": "<role>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

ingestInboundReply

POST/api/inbound-replies/ingest

No sessionPermission: public

ingestInboundReply

curl
curl -X POST 'https://www.notificado.co/api/inbound-replies/ingest' \
  -H 'content-type: application/json' \
  -d '"<body>"'
TypeScript
const response = await fetch('https://www.notificado.co/api/inbound-replies/ingest', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify("<body>"),
});
const result = await response.json();
Example response
200
{
  "messageId": "<messageId>",
  "outcome": "<outcome>",
  "type": "<type>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

recordPixel

POST/api/pixels/record

No sessionPermission: public

recordPixel

Parameters of recordPixel
NameInTypeRequired
recipientTokenBodystringYes
curl
curl -X POST 'https://www.notificado.co/api/pixels/record' \
  -H 'content-type: application/json' \
  -d '{"recipientToken":"<recipientToken>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/pixels/record', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "recipientToken": "<recipientToken>"
  }),
});
const result = await response.json();
Example response
200
{
  "eventId": "<eventId>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

acknowledgeReceipt

POST/api/receipts/acknowledge

No sessionPermission: public

acknowledgeReceipt

Parameters of acknowledgeReceipt
NameInTypeRequired
recipientTokenBodystring 1–64Yes
curl
curl -X POST 'https://www.notificado.co/api/receipts/acknowledge' \
  -H 'content-type: application/json' \
  -d '{"recipientToken":"<recipientToken>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/receipts/acknowledge', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "recipientToken": "<recipientToken>"
  }),
});
const result = await response.json();
Example response
200
{
  "acknowledgedAt": "<acknowledgedAt>",
  "created": true,
  "eventId": "<eventId>",
  "ok": true
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

ingestSesEvent

POST/api/ses-events/ingest

No sessionPermission: public

ingestSesEvent

curl
curl -X POST 'https://www.notificado.co/api/ses-events/ingest' \
  -H 'content-type: application/json' \
  -d '"<body>"'
TypeScript
const response = await fetch('https://www.notificado.co/api/ses-events/ingest', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify("<body>"),
});
const result = await response.json();
Example response
200
{
  "messageId": "<messageId>",
  "outcome": "<outcome>",
  "type": "<type>"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

wompiWebhook

POST/api/webhooks/wompi

No sessionPermission: public

wompiWebhook

Parameters of wompiWebhook
NameInTypeRequired
environmentBodystring 1–20No
eventBodystring 1–80Yes
sent_atBodystring 1–40No
curl
curl -X POST 'https://www.notificado.co/api/webhooks/wompi' \
  -H 'content-type: application/json' \
  -d '{"event":"<event>"}'
TypeScript
const response = await fetch('https://www.notificado.co/api/webhooks/wompi', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "event": "<event>"
  }),
});
const result = await response.json();
Example response
200
{
  "eventKey": "<eventKey>",
  "outcome": "queued"
}

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

Staff console

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

abuseOverview

GET/_x/query/abuse-overview

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

billingKpis

GET/_x/query/billing-kpis

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

catalogSnapshot

GET/_x/query/catalog-snapshot

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

deliverability

GET/_x/query/deliverability

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

evidenceHealth

GET/_x/query/evidence-health

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

jobQueues

GET/_x/query/job-queues

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

opsAlerts

GET/_x/query/ops-alerts

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

opsOverview

GET/_x/query/ops-overview

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

pendingStaffConfirmations

GET/_x/query/pending-staff-confirmations

Notificado staff onlyPermission: admin:tokens:self

pendingStaffConfirmations

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

providerHealth

GET/_x/query/provider-health

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

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

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

Errors

  • 400 X_INPUT_INVALID or X_CURSOR_INVALID
  • 403 policy denied

decideApproval

POST/api/approvals/decide

Notificado staff onlyPermission: admin:approvals:decide

decideApproval

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listApprovals

POST/api/approvals/list

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminArchiveCoupon

POST/api/archive-coupons/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewAsOrg

POST/api/as-orgs/view

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

exportAudit

POST/api/audits/export

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listAudit

POST/api/audits/list

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminCreateCoupon

POST/api/create-coupons/admin

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

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

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

Errors

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

viewCustomer360

POST/api/customer360s/view

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminDownloadGatewayEvent

POST/api/download-gateway-events/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminExportEvidenceZip

POST/api/export-evidence-zips/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

cancelJob

POST/api/jobs/cancel

Notificado staff onlyPermission: admin:jobs:write

cancelJob

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requeueJob

POST/api/jobs/requeue

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewKycDocument

POST/api/kyc-documents/view

Notificado staff onlyPermission: kyc:review

viewKycDocument

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listKycQueue

POST/api/kyc-queues/list

Notificado staff onlyPermission: kyc:reviewMCP tool: listKycQueue

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

approveKyc

POST/api/kycs/approve

Notificado staff onlyPermission: kyc:reviewMCP tool: approveKyc

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

rejectKyc

POST/api/kycs/reject

Notificado staff onlyPermission: kyc:reviewMCP tool: rejectKyc

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

staffLedgerList

POST/api/ledger-lists/staff

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminListCoupons

POST/api/list-coupons/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminListPayments

POST/api/list-payments/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

requestManualInvoiceUpload

POST/api/manual-invoice-uploads/request

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

pendingManualInvoices

POST/api/manual-invoices/pending

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

recordManualInvoice

POST/api/manual-invoices/record

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

searchNotifications

POST/api/notifications/search

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

searchOrgs

POST/api/orgs/search

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

suspendOrg

POST/api/orgs/suspend

Notificado staff onlyPermission: abuse:write

suspendOrg

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewOrg

POST/api/orgs/view

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminPaymentDetail

POST/api/payment-details/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewRawEvent

POST/api/raw-events/view

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

viewRecipientTimeline

POST/api/recipient-timelines/view

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminReconcilePayment

POST/api/reconcile-payments/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminReissueConstancia

POST/api/reissue-constancias/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

adminRequestRefund

POST/api/request-refunds/admin

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

setSenderLimit

POST/api/sender-limits/set

Notificado staff onlyPermission: abuse:write

setSenderLimit

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmStaffAction

POST/api/staff-actions/confirm

Notificado staff onlyPermission: admin:tokens:self

confirmStaffAction

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

confirmStaffMfa

POST/api/staff-mfas/confirm

Notificado staff onlyPermission: admin:read

confirmStaffMfa

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

enrolStaffMfa

POST/api/staff-mfas/enrol

Notificado staff onlyPermission: admin:read

enrolStaffMfa

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

issueStaffToken

POST/api/staff-tokens/issue

Notificado staff onlyPermission: admin:tokens:self

issueStaffToken

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listStaffTokens

POST/api/staff-tokens/list

Notificado staff onlyPermission: admin:tokens:self

listStaffTokens

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

revokeStaffToken

POST/api/staff-tokens/revoke

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

revokeStaffToken

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

checkStorageLock

POST/api/storage-locks/check

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

addSupportNote

POST/api/support-notes/add

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

listSupportNotes

POST/api/support-notes/list

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

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

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

liftSuspension

POST/api/suspensions/lift

Notificado staff onlyPermission: abuse:write

liftSuspension

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID

triggerTestError

POST/api/test-errors/trigger

Notificado staff onlyPermission: admin:ops:test-error

triggerTestError

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

Errors

  • 400 X_INPUT_INVALID
  • 403 policy denied
  • 422 X_BODY_INVALID