Caché
Los informes se guardan en la caché del servidor por nombre de host y lista de secciones, de modo que pedir las mismas secciones de nuevo dentro del tiempo de caché devuelve la misma observación con "cached": true y sus horas observedAt originales. Las cabeceras Cache-Control indicadas arriba también permiten que los navegadores y la CDN reutilicen una respuesta durante poco tiempo. No hay ningún parámetro para forzar una consulta nueva.
CORS
Los endpoints de esta página envían Access-Control-Allow-Origin: * y responden a las solicitudes previas OPTIONS (pre-flight), solo para GET. Puede llamarlos desde una página de otro origen. Nunca leen cookies, así que no intervienen credenciales.
Uso razonable
Cada solicitud desencadena consultas reales a registros de extensión, resolvers DNS y al propio sitio consultado. Use la API para herramientas interactivas, paneles y comprobaciones ocasionales de dominios que tenga motivos para revisar. No rastree listas de dominios, no rote direcciones para esquivar los límites y no revenda los resultados. La política de uso aceptable se aplica al tráfico de la API exactamente igual que al sitio.
Outbound webhooks
Signed-in members can have watch alerts, expiry reminders and marketplace notices posted to a URL they own: a Slack incoming webhook or a generic https endpoint (workspace → Settings → Notification channels). This section documents what the receiver gets. It is outbound only: OrbitProbe never accepts requests on these URLs, and there is no inbound API.
Receivers must be https on a public host (default port, no credentials; private, local and reserved hosts are refused, and the host is resolved and checked again at send time). Redirects are not followed. A delivery counts as done when the receiver answers 2xx; after five failed deliveries in a row the webhook is switched off and the owner sees a notice in the workspace.
Request
| Nombre | Descripción |
|---|---|
| POST | JSON body, Content-Type: application/json; charset=utf-8, User-Agent: OrbitProbe-Webhook/1.0 |
| X-OrbitProbe-Event | The kind (see below). |
| X-OrbitProbe-Delivery | The delivery id (ntf_<number>). Repeated on a retry, so you can de-duplicate. |
| X-OrbitProbe-Signature | Generic endpoints only: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>"> with the signing secret shown in Settings. |
Body (generic endpoints)
| Nombre | Descripción |
|---|---|
| id | Delivery id, the same as X-OrbitProbe-Delivery. |
| kind | One of the kinds below. |
| category | watch, expiry, market or test. |
| title, text | The notification in the account’s language: the same wording the push notification carries. Counts are "N of M resolvers", never percentages. |
| url | Where to look in the workspace. |
| createdAt | When the event was queued (ISO 8601, UTC). |
| account | The recipient’s account id, so one receiver can serve several accounts. |
| data | The raw event as stored: domain, counts, listing id, amount in integer minor units and currency, and so on. Fields vary by kind; anything missing was not measured, never "no". |
{
"id": "ntf_1042",
"kind": "watch-changed",
"category": "watch",
"title": "Watch: unexpected change",
"text": "example.com TXT: 9 of 12 resolvers return values that differ from the guarded baseline.",
"url": "https://www.orbitprobe.com/app/watch/00000000-0000-4000-8000-000000000000",
"createdAt": "2026-01-01T00:00:00.000Z",
"account": "00000000-0000-4000-8000-0000000000aa",
"data": {
"domain": "example.com",
"kind": "dns-change",
"record_type": "TXT",
"name": "example.com",
"matched": 3,
"total": 12,
"failed": 0,
"differing": 9,
"watch_id": "00000000-0000-4000-8000-000000000000",
"event_id": 77
}
}Body (Slack)
Slack incoming webhooks receive {"text": "…"} only: title, text and URL on three lines, no Block Kit and no attachments, so the message renders in every Slack client and in Slack-compatible receivers such as Mattermost or Rocket.Chat.
{
"text": "*Watch: unexpected change*\nexample.com TXT: 9 of 12 resolvers return values that differ from the guarded baseline.\nhttps://www.orbitprobe.com/app/watch/…"
}Verifying the signature
Recompute the HMAC over "<t>.<raw body>" with your secret, compare in constant time, and reject timestamps older than five minutes. Do not parse and re-serialise the JSON before hashing: sign the bytes as received.
// Node.js receiver: verify X-OrbitProbe-Signature before trusting the body
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(secret, rawBody, header, nowSeconds = Math.floor(Date.now() / 1000)) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? '');
if (!m || Math.abs(nowSeconds - Number(m[1])) > 300) return false;
const expected = createHmac('sha256', secret).update(`${m[1]}.${rawBody}`).digest('hex');
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(m[2], 'hex'));
}Kinds
watch-changed, watch-target, watch-failed, watch-recovered, watch-partial · expiry · offer-received, offer-countered, offer-accepted, offer-rejected, offer-withdrawn, offer-expired, listing-submitted, listing-approved, listing-paused, listing-removed, agreement-cancelled · test (the "Send test" button).
Limits
At most 5 webhooks per account and 20 posts per account per hour; beyond that, events still reach the in-app inbox and e-mail but are not posted. Deliveries are retried up to five times over later runs of the five-minute job. An "offer-accepted" event records an agreement only: no payment, escrow or transfer is implied.
Descripción OpenAPI
A partir del mismo código se genera un documento OpenAPI 3.1 de estos endpoints, legible por máquinas: /api/openapi.json